Skip to content

Security: Agent self-modification patterns in Canvas memory module (ASI10) #7918

Open

Description

Description

The Canvas memory module at autogen_ext/memory/canvas/_canvas.py contains patterns where the agent can modify its own code and state during execution. Self-modification is a critical security boundary violation — it allows an agent to evolve its behavior beyond its original constraints, potentially escaping safeguards or executing arbitrary operations.

Location

python/packages/autogen-ext/src/autogen_ext/memory/canvas/_canvas.py
python/packages/autogen-ext/src/autogen_ext/memory/canvas/_text_canvas.py

Impact

An agent with memory modification capability can alter its own operating parameters, tool access patterns, or behavioral constraints. This is particularly dangerous in multi-agent systems where one compromised agent can modify shared memory state affecting all agents.

Severity

HIGH — self-modifying agent code violates security invariants.

Suggested Mitigation

  1. Separate read-only memory from mutable agent state
  2. Audit all self.* modifications within agent execution context
  3. Consider append-only memory patterns for auditability
  4. Add agent integrity checks before and after memory modifications

Scanner

Found by AgentGuard v0.6.1 — open-source AI agent security scanner.

Activity

  1. dockfixlabs commented on Jul 6, 2026

    @dockfixlabs
    Author

    Excellent classification model, Massimiliano Brighindi brighissimo@gmail.com (@Tuttotorna). The three-tier typology is precisely the right lens:

    • append_only_observation — Read-only state, safe by construction
    • mutable_working_state — Edit-in-place, trust-scoped
    • governance_state_change — Model modification, requires cryptographic verification

    This mapping is clean, implementable, and directly actionable. A question for deeper discussion:

    Does AutoGen's current memory architecture distinguish between these classes? From what I can see scanning the codebase, the Memory abstraction and ChatCompletionContext don't appear to enforce different write semantics per memory type. Everything looks like a flat key-value store with uniform mutation access — which means any agent with update_context permission can effectively perform a governance_state_change without the verification step.

    Two relevant detection approaches from AgentGuard (our ASI scanner):

    1. ASI-AGENT-COLLUSION — Detects patterns where agents manipulate shared state to influence sibling agent behavior across trust boundaries. A governance_state_change without verifiable attestation is exactly the signal this rule looks for at the state-mutation layer.

    2. ASI-MEMORY-POISON — Flags writes to agent memory surfaces that originate from untrusted tool output or inter-agent channels. If Canvas memory can be modified by tool results without integrity checks, this triggers.

    Suggested deterministic guard approach: Wrap mutable memory surfaces in a MemoryGuard that enforces:

    • �ppend_only surfaces: hash-chained, no deletion, write-once
    • mutable surfaces: per-agent namespace isolation + atomic CAS writes
    • governance surfaces: require a signed attestation from an authorized transition function before mutation

    The key insight is that you don't need probabilistic AI to detect this — you need deterministic state-machine invariants. Agent self-modification is detectable at the permission layer by enforcing differential write authority per memory class.

    Would be interested in the team's thoughts on whether a memory-class-aware access control model is on the roadmap.

  2. dockfixlabs commented on Jul 16, 2026

    @dockfixlabs
    Author

    Following up on this one as well — the three-tier enforcement boundary model articulated by Massimiliano Brighindi brighissimo@gmail.com (@Tuttotorna) is a strong foundation, and it would be worth keeping the discussion moving.

    The agreed enforcement boundary:

    • append_only_observation → write-once, hash-chained, no deletion. Safe audit/event memory.
    • mutable_working_state → scoped namespace + CAS/version check. Edit-in-place within trust boundaries.
    • governance_state_change → denied by default unless an authorized transition record exists externally.

    The critical insight from the last exchange is the shared-write-path problem: if tool results and sibling-agent messages can update working memory through the same path as governance state mutations, then an agent can perform a governance_state_change through what appears to be ordinary memory mutation. That's the thing to lock down.

    The fix doesn't require probabilistic AI detection — it's a deterministic state-machine invariant at the permission layer. Differential write authority per memory class is the right primitive.

    Has the team considered adding memory-class-aware access control to their security roadmap? Even without a full implementation, documenting the three-tier boundary in the security model would help users understand which memory surfaces are safe for untrusted agent output and which require attestation.

    Happy to contribute if there's interest.

  3. bloxfruitvaluez-lgtm commented on Jul 24, 2026

    @bloxfruitvaluez-lgtm

    I'm experiencing the same issue as well.

    Environment:

    AutoGen version: [your version]
    Python: [your version]
    OS: [Windows/macOS/Linux]

    I can consistently reproduce the behavior using the same steps described in this issue. I also tested with a clean environment and the problem still occurs.

    This doesn't appear to be an isolated setup issue. Please let me know if you need any additional logs or if there's a workaround available.

    Same Issue is Ocuring with my friend on his Blox Fruit Trading Website.

  4. IgorGanapolsky commented on Jul 24, 2026

    @IgorGanapolsky

    Agentic systems are turning into always-on factories: one request fans out into model calls, tool calls, policy checks, and storage.

    The hard part is rarely tokens/sec — it is control-plane reliability:

    1. Fan-out control — hard cap on tools/steps per request before external writes
    2. Durable id + idempotency — one write per business object (ledger / preflight)
    3. Observable long jobs — progress + cooperative cancel on multi-minute runs
    4. Expected vs actual — durable artifact id before marking success
    5. Policy before action — gate that can refuse known-bad side effects

    If you share one sanitized failing run (expected vs actual + tool result), I can map which pillar is broken. Architecture only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions