# How to Use Sly-Data for Secure Data Handling Between Agents in Neuro-SAN

> Learn how to use Sly-Data for secure data handling between agents. This out-of-band Python dictionary safely transmits secrets and session state without LLM prompts.

- Repository: [Cognizant AI Lab/neuro-san-studio](https://github.com/cognizant-ai-lab/neuro-san-studio)
- Tags: how-to-guide
- Published: 2026-02-27

---

**Sly-Data is an out-of-band Python dictionary that passes securely between agents without ever appearing in LLM prompts, enabling safe transmission of secrets and session state.**

Sly-Data provides a protected data channel for the `cognizant-ai-lab/neuro-san-studio` framework, allowing sensitive information to flow through agent networks while remaining invisible to the language model. This mechanism ensures that API keys, session identifiers, and operational counters persist across tool invocations without risking exposure in chat logs or prompt telemetry.

## What Is Sly-Data and Why It Matters

Sly-Data functions as a **write-once, read-many** session dictionary that travels alongside every `ChatRequest` through the Neuro-SAN runtime. Unlike standard tool arguments that get serialized into LLM prompts, `sly_data` remains strictly internal to the code execution layer.

The security model operates on three core principles:

- **Out-of-band transmission**: The dictionary is passed directly to `CodedTool.invoke()` methods without passing through the LLM context window
- **Automatic exclusion from logging**: Because `sly_data` never enters the prompt pipeline, it avoids external telemetry and audit logs by default
- **Explicit egress control**: Front-man agent configurations whitelist which keys may return to the client, preventing accidental secret leakage

## How Sly-Data Works Under the Hood

### The Out-of-Band Architecture

In [`pandas/core/frame.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/pandas/core/frame.py) (analogous patterns), data flows through explicit channels. Similarly, Neuro-SAN implements Sly-Data through a parallel parameter path in the agent network designer.

When a client initiates a chat, the runtime creates a fresh `sly_data` dictionary (empty if omitted) and injects it into every tool invocation:

```python

# Conceptual flow inside Neuro-SAN runtime

sly_data = request.sly_data or {}
for tool in agent_network:
    result = tool.invoke(args, sly_data)  # Same dict reference passed through chain

```

This single reference persists across the entire call chain, allowing downstream tools to see mutations made by upstream tools.

### Session Persistence and State Management

The framework maintains session-level state through this dictionary mechanism. For example, in [`coded_tools/tools/now_agents/nowagent_api_send_message.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/coded_tools/tools/now_agents/nowagent_api_send_message.py), the tool stores a ServiceNow session identifier:

```python
def invoke(self, args: Dict[str, Any], sly_data: Dict[str, Any]) -> str:
    # ... API call to ServiceNow ...

    tool_response = response.json()
    user_id = tool_response["metadata"]["user_id"]
    session_id = tool_response["metadata"]["session_id"]
    
    # Persist session for downstream retrieval

    sly_data["session_path"] = f"{user_id}_{session_id}"
    return tool_response

```

Subsequent tools in the network read `sly_data["session_path"]` to continue the same conversation thread without re-authenticating.

## Implementing Sly-Data in Coded Tools

### Reading and Writing Session Data

Every `CodedTool` implementation receives `sly_data` as the second parameter to `invoke()`. Tools can read existing values, perform operations, and write new entries for downstream consumption.

In [`coded_tools/basic/accountant_sly.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/coded_tools/basic/accountant_sly.py), a cost-tracking tool demonstrates the write pattern:

```python

# coded_tools/basic/accountant_sly.py

class AccountantSly(CodedTool):
    """Updates a running cost kept in sly_data."""
    
    def invoke(self, args: Dict[str, Any], sly_data: Dict[str, Any]) -> Dict[str, Any]:
        # Read current value (default to 0.0 if absent)

        running_cost = float(sly_data.get("running_cost", 0.0))
        
        # Update value

        updated = running_cost + 3.0  # Add flat $3 per call

        
        # Write back to shared dictionary

        sly_data["running_cost"] = updated  # Mutation persists downstream

        
        return {"running_cost": updated}

```

All subsequent tools in the agent network see the updated `running_cost` value without any explicit database calls or external state management.

### Tracking Costs Across Agent Calls

The Accountant pattern extends naturally to distributed cost tracking. Because `sly_data` flows through the entire agent network, multiple tools can increment counters:

```python

# In a database query tool

def invoke(self, args, sly_data):
    sly_data["db_query_count"] = sly_data.get("db_query_count", 0) + 1
    # ... perform query ...

# In an external API tool  

def invoke(self, args, sly_data):
    sly_data["api_call_count"] = sly_data.get("api_call_count", 0) + 1
    # ... perform API call ...

```

The front-man agent can then return these aggregated statistics to the client via the whitelist mechanism.

## Configuring Sly-Data Security and Whitelisting

Security enforcement happens at the front-man agent level through HOCON configuration. The `allowed_sly_data_keys` parameter explicitly defines which dictionary entries may exit the agent network back to the client.

In your front-man agent definition:

```hocon
frontman {
  allowed_sly_data_keys = ["running_cost", "session_path", "db_query_count"]
}

```

This configuration ensures that sensitive keys like `api_key` or internal `session_token` values remain trapped inside the agent network even if accidentally written to `sly_data`. Only the explicitly enumerated keys pass through to the final response.

## Client-Side Integration

When initiating a conversation through the Python SDK, clients attach `sly_data` directly to the chat request:

```python
from neuro_san import NeuroSANClient

client = NeuroSANClient(base_url="https://api.example.com")

# Initialize with sensitive data and state

sly_data = {
    "api_key": "sk_live_...",
    "running_cost": 0.0,
    "customer_tier": "enterprise"
}

response = client.chat(
    user_text="Generate a forecast for Q4",
    sly_data=sly_data  # Hidden from LLM, visible to tools

)

# Access whitelisted return values

if "sly_data" in response:
    print("Total cost:", response["sly_data"]["running_cost"])

```

The SDK forwards the dictionary unchanged to the Neuro-SAN runtime, where it remains isolated from prompt engineering and LLM processing.

## Summary

- **Sly-Data** provides an out-of-band dictionary that flows through agent networks without entering LLM prompts, ensuring secrets remain secure.
- The `sly_data` parameter appears in every `CodedTool.invoke()` signature, enabling tools to read, update, and pass state downstream.
- Session persistence works by writing identifiers (like `session_path`) to `sly_data`, allowing subsequent tools to continue conversations without re-authentication.
- Security enforcement relies on the front-man's `allowed_sly_data_keys` configuration, which explicitly whitelists dictionary keys that may return to clients.
- Implementation requires no external databases—state lives in the Python dictionary reference that persists for the duration of the request.

## Frequently Asked Questions

### What is the difference between Sly-Data and regular tool arguments?

Regular tool arguments get serialized into the LLM prompt context, making them visible to the language model and potentially logged in telemetry. **Sly-Data** travels through a separate code channel directly to `CodedTool.invoke()` methods, remaining completely invisible to the LLM and excluded from prompt logs by default.

### Can Sly-Data persist across multiple user messages in a conversation?

Yes. When using session-based agents like the NowAgent suite, tools store session identifiers in `sly_data` (such as `session_path`), and the framework maintains this dictionary across the conversation lifecycle. Subsequent messages in the same session access the same `sly_data` reference, allowing continuous state accumulation.

### How do I prevent sensitive Sly-Data keys from leaking to the client?

Configure the front-man agent's `allowed_sly_data_keys` list in your HOCON configuration file. Only keys explicitly listed there will be serialized back to the client response. Any keys written to `sly_data` that are not in this whitelist remain internal to the agent network and are discarded after processing.

### Is Sly-Data available when using the REST API directly?

Yes. When calling the Neuro-SAN REST API directly, include a `sly_data` object in your JSON request payload alongside the `user_text`. The server deserializes this into the Python dictionary passed to all coded tools. Ensure your client handles the response to extract any whitelisted keys returned in the `sly_data` field of the response body.