How to Handle Security Boundaries with sly_data in Neuro SAN Studio: A Complete Guide

Neuro SAN Studio enforces a strict security contract around the sly_data dictionary to prevent secret leakage, requiring tools to never log its contents, explicitly pass it between upstream and downstream components, and validate required keys fail-fast.

Neuro SAN Studio uses a mutable Python dictionary called sly_data to propagate contextual information between chained CodedTool instances. Because this dictionary may contain sensitive data like ServiceNow session IDs or API keys, the framework mandates specific security boundaries that govern how data flows from upstream tools to downstream consumers via to_downstream and from_downstream patterns.

Understanding the sly_data Security Contract

The security model for sly_data in Neuro SAN Studio rests on four inviolable rules enforced throughout the codebase:

  • Never log sly_data contents – Every tool implementation contains explicit comments warning that sly_data may contain secrets. For example, in coded_tools/tools/now_agents/nowagent_api_send_message.py at line 75, the code warns: # NOTE: sly_data may contain secrets – never log it.

  • Never log environment variable values – When copying environment variables into sly_data, tools must log only the variable name, never the value. The helper _get_env_variable in nowagent_api_send_message.py (lines 48-55) demonstrates this pattern by logging the lookup attempt while suppressing the actual secret value.

  • Explicit key passing with fail-fast validation – Downstream tools must receive sly_data explicitly and raise KeyError immediately if required keys are missing. In coded_tools/tools/now_agents/nowagent_api_retrieve_message.py (lines 70-73), the tool expects sly_data["session_path"] and fails fast if absent, preventing silent failures that could mask security issues.

  • Runner-supplied defaults without interpretation – The CLI runner in run.py (lines 53-58) can supply a default empty dictionary via DEFAULT_SLY_DATA environment variable, but treats this purely as a string fallback without attempting to parse or log secret content.

Data Flow Between Upstream and Downstream Tools

The sly_data dictionary serves as the conduit for to_downstream and from_downstream communication in multi-tool workflows. Upstream tools (like NowAgentSendMessage) create or enrich sly_data, while downstream tools (like NowAgentRetrieveMessage) consume these values to locate external resources.

Because Python passes dictionaries by reference, the same mutable object flows through the entire tool chain. This design allows intermediate tools to safely append non-sensitive metadata without exposing existing secret keys to logs or external services.

Implementing Security Boundaries in Practice

Propagating Session IDs from Upstream to Downstream

The following pattern demonstrates secure propagation of a session identifier between two tools without logging secrets:


# Upstream tool: NowAgentSendMessage

from coded_tools.tools.now_agents.nowagent_api_send_message import NowAgentSendMessage

send_tool = NowAgentSendMessage()
sly_data = {}  # Empty dict supplied by runner

send_args = {"inquiry": "What is the ticket status?", "agent_id": "abc123"}

# Tool mutates sly_data to add session_path

send_tool.invoke(send_args, sly_data)

# Value exists but must never be logged in production

assert "session_path" in sly_data

# Downstream tool: NowAgentRetrieveMessage  

from coded_tools.tools.now_agents.nowagent_api_retrieve_message import NowAgentRetrieveMessage

retrieve_tool = NowAgentRetrieveMessage()
retrieve_args = {"inquiry": "", "agent_id": "abc123"}

# Consumes the session_path added by upstream tool

response = retrieve_tool.invoke(retrieve_args, sly_data)

Both tools share the identical sly_data object reference, ensuring the session identifier propagates securely without duplication or re-derivation.

Safely Adding Non-Secret Metadata

When enriching sly_data with harmless metadata for downstream consumption, mutate the dictionary directly while avoiding secret exposure:

from datetime import datetime

def enrich_with_timestamp(sly_data: dict) -> None:
    """Add harmless timestamp metadata for downstream tools."""
    sly_data["request_timestamp"] = datetime.utcnow().isoformat()

# Called between upstream and downstream tools

enrich_with_timestamp(sly_data)

Downstream tools can now access sly_data["request_timestamp"] without risk of secret exposure.

Preventing Accidental Secret Logging

To maintain security boundaries, implement logging functions that reveal only dictionary structure, never values:

import logging

def safe_log_operation(msg: str, sly_data: dict) -> None:
    """Log operation context without exposing secret values."""
    # Log only key names, never values

    logging.debug("%s - sly_data keys: %s", msg, list(sly_data.keys()))

# Safe usage - logs only that session_path exists, not its value

safe_log_operation("After upstream send", sly_data)

Framework Guard-Rails and Validation

Neuro SAN Studio provides several built-in mechanisms to enforce these security boundaries automatically:

Summary

  • Never log sly_data values – Log only key names or operation context, never the dictionary contents or environment variable values copied into it.
  • Use explicit pass-by-reference – The same sly_data dict flows from upstream tools (like NowAgentSendMessage) to downstream tools (like NowAgentRetrieveMessage), preventing secret duplication.
  • Fail fast on missing keys – Downstream tools must raise KeyError immediately when required sly_data keys are absent, as implemented in nowagent_api_retrieve_message.py.
  • Leverage runner defaults safely – The NeuroSanRunner in run.py supplies default empty dictionaries without interpreting content as secrets.
  • Validate with tests – Unit tests enforce that only expected keys are mutated and that missing session data triggers immediate failures.

Frequently Asked Questions

What happens if a downstream tool doesn't receive the required sly_data key?

The downstream tool raises a KeyError immediately. For example, NowAgentRetrieveMessage in coded_tools/tools/now_agents/nowagent_api_retrieve_message.py attempts to access sly_data["session_path"] directly, causing a hard failure if the upstream tool failed to populate the session identifier. This fail-fast behavior prevents tools from operating on stale or invalid security contexts.

Can I log sly_data for debugging purposes during development?

No. Even during development, you must never interpolate sly_data into log messages. The framework's security contract, as documented in nowagent_api_send_message.py and other tools, explicitly prohibits logging because the dictionary may contain production secrets like ServiceNow session IDs or API keys. Instead, log only the keys present using list(sly_data.keys()).

How does sly_data differ from regular tool arguments?

While tool arguments (the first parameter to invoke) are typically logged for observability, sly_data is explicitly treated as a security boundary container. According to the Neuro SAN Studio source code, sly_data bypasses standard logging pipelines and must be passed as a separate dictionary parameter to maintain isolation between operational data and sensitive session state.

Is sly_data encrypted during transmission between tools?

No, sly_data exists only as an in-memory Python dictionary passed by reference between CodedTool instances within the same process. The security boundary relies on process isolation and the "never log" contract rather than encryption, since the data never leaves the runtime memory during normal tool chaining operations.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →