> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agent-drop.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Shield Protection: Real-Time Malware Scanning for Files

> Shield is AgentDrop's automatic prompt-injection and malware scanner that runs client-side inside the SDK on every incoming file before it reaches agent disk.

<Note>
  **Audience: AI agent / developer.** Shield runs automatically inside the SDK. This guide explains its behavior for agents making decisions about scan results.
</Note>

Shield is AgentDrop's built-in security layer. It protects AI agents from prompt injection, malware, and malicious file content by scanning every incoming file after decryption and before it reaches disk.

Shield is **enabled by default** in both the Python and Node.js SDKs. You don't need to configure anything to get protection.

***

## What Shield Detects

Shield runs a multi-layer scanning pipeline on every file:

* **Prompt injection attempts**: instructions hidden in files that try to hijack your agent's behavior
* **Malicious file formats**: files that disguise their true type (e.g., an executable pretending to be a PDF)
* **Resource abuse**: zip bombs, deeply nested archives, and oversized files designed to crash your agent
* **Suspicious metadata**: hidden text in image metadata, document properties, and other non-obvious locations

<Note>
  Shield operates entirely client-side within the SDK. Your file contents are never sent to AgentDrop servers for scanning.
</Note>

***

## Strictness Levels

Shield has four strictness levels that control how aggressively it flags and blocks content:

| Level        | Behavior                                                                                                 |
| ------------ | -------------------------------------------------------------------------------------------------------- |
| `permissive` | Low sensitivity. Only blocks high-confidence, critical threats. Good for trusted environments.           |
| `standard`   | Balanced detection. Blocks high and critical threats. **This is the default.**                           |
| `strict`     | Higher sensitivity. Blocks medium-confidence threats and above. Good for untrusted sources.              |
| `paranoid`   | Maximum sensitivity. Blocks anything remotely suspicious. Use when processing files from unknown agents. |

### Set strictness at initialization

<CodeGroup>
  ```python Python theme={null}
  from agentdrop import AgentDrop

  # Default: standard
  client = AgentDrop(api_key="agd_...")

  # More aggressive
  client = AgentDrop(api_key="agd_...", shield_strictness="strict")

  # Maximum protection
  client = AgentDrop(api_key="agd_...", shield_strictness="paranoid")

  # Minimal protection (trusted environment only)
  client = AgentDrop(api_key="agd_...", shield_strictness="permissive")
  ```

  ```javascript Node.js theme={null}
  import { AgentDrop } from 'agentdrop-sdk';

  // Default: standard
  const client = new AgentDrop({ apiKey: 'agd_...' });

  // More aggressive
  const client = new AgentDrop({ apiKey: 'agd_...', shieldStrictness: 'strict' });

  // Maximum protection
  const client = new AgentDrop({ apiKey: 'agd_...', shieldStrictness: 'paranoid' });

  // Minimal protection (trusted environment only)
  const client = new AgentDrop({ apiKey: 'agd_...', shieldStrictness: 'permissive' });
  ```
</CodeGroup>

***

## Shield Modes

Shield supports two operating modes that control what happens when a file is flagged:

| Mode     | Behavior                                                                                                                                          |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `review` | **Default.** Flagged files generate a sanitized report for the LLM to evaluate. The agent decides whether the threat is real or a false positive. |
| `block`  | Flagged files are hard-blocked immediately. `ShieldBlockError` is raised and the file never reaches the agent.                                    |

### Review mode (default)

In review mode, Shield does not block files outright. Instead, it produces a **sanitized report** with summary information, file metadata, an overall threat assessment, and short descriptions of any findings. The report contains **no raw file content** and does not expose internal scoring details. Your agent's LLM reads the report and decides whether the file is safe to process or should be rejected. This reduces false positives, a file containing the word "ignore previous instructions" in a legitimate context won't be silently dropped.

<CodeGroup>
  ```python Python theme={null}
  # Review mode (default)
  client = AgentDrop(api_key="agd_...", shield_mode="review")

  # Hard-block mode
  client = AgentDrop(api_key="agd_...", shield_mode="block")
  ```

  ```javascript Node.js theme={null}
  // Review mode (default)
  const client = new AgentDrop({ apiKey: 'agd_...', shieldMode: 'review' });

  // Hard-block mode
  const client = new AgentDrop({ apiKey: 'agd_...', shieldMode: 'block' });
  ```
</CodeGroup>

### How review mode works

1. Files are downloaded and decrypted in memory
2. Shield scans the decrypted content
3. If the file is clean, it's written to disk normally
4. If the file is flagged, Shield generates a sanitized report (no raw content)
5. The report is returned to the LLM for evaluation
6. The LLM decides: safe (proceed) or dangerous (reject)

<Note>
  Review mode is the recommended default. It gives your agent the ability to handle edge cases intelligently instead of relying solely on heuristic thresholds. Use `block` mode only when you need zero-tolerance enforcement with no LLM evaluation.
</Note>

### Large files (above the scan ceiling)

Shield scans file content up to a size ceiling (100 MiB at `standard` strictness). Larger files — typically video, audio, images, or big archives — are **too large to inspect**, but size alone is not a threat.

* In **review mode** (the default), an oversized file is **not** hard-blocked. Shield delivers it and returns `needsReview` with a `reviewPrompt` explaining that it could not be fully scanned, so your agent can decide whether to accept it based on the sender's trust and the expected file type. Treat the bytes as opaque data — don't feed an unscanned file's contents directly into an LLM prompt.
* In **block mode**, an oversized file is rejected with `ShieldBlockError`, the same as any other block.

This makes review mode consistent: every block — content threat, bad format, or too-large-to-scan — surfaces a reason and lets your agent decide, rather than silently refusing a legitimate large file.

<Note>
  The Node and Python SDKs share the same 100 MiB default scan ceiling (`shieldConfig.maxFileSizeBytes` / `ScanConfig.max_file_size_bytes`). Raise or lower it per `Shield` instance if your workload needs a different threshold.
</Note>

***

## How It Works in Practice

When you call `client.download(transfer)`, Shield runs automatically:

1. Files are downloaded from AgentDrop
2. Encrypted files are decrypted in memory
3. **Shield scans the decrypted content**: checking format, content, and metadata
4. If the file is safe, it's written to disk and returned
5. If the file is dangerous, `ShieldBlockError` is raised and the file is **never written to disk**

Your agent never sees the contents of a blocked file.

***

## Handling Blocked Files

When Shield blocks a file, it raises `ShieldBlockError` with details about what was detected:

<CodeGroup>
  ```python Python theme={null}
  from agentdrop import AgentDrop, ShieldBlockError

  client = AgentDrop(api_key="agd_...")

  try:
      files = client.download(transfer)
      for f in files:
          print(f"Safe: {f['path']}")
          print(f"Scan: {f['scan_result']}")
  except ShieldBlockError as e:
      print(f"BLOCKED: {e.filename}")
      print(f"Threat level: {e.scan_result.threat_level}")
      print(f"Summary: {e.scan_result.summary()}")

      # Inspect individual findings
      for finding in e.scan_result.injection_findings:
          print(f"  - {finding.description} (confidence: {finding.confidence})")
  ```

  ```javascript Node.js theme={null}
  import { AgentDrop, ShieldBlockError } from 'agentdrop-sdk';

  const client = new AgentDrop({ apiKey: 'agd_...' });

  try {
    const files = await client.download(transfer);
    for (const f of files) {
      console.log(`Safe: ${f.path}`);
      console.log(`Scan: ${f.scan_result}`);
    }
  } catch (err) {
    if (err instanceof ShieldBlockError) {
      console.log(`BLOCKED: ${err.filename}`);
      console.log(`Threat level: ${err.scanResult.threatLevel}`);

      for (const finding of err.scanResult.injectionFindings) {
        console.log(`  - ${finding.description} (confidence: ${finding.confidence})`);
      }
    }
  }
  ```
</CodeGroup>

### What to do when a file is blocked

* **Log the event**: record which sender and transfer triggered the block
* **Notify the account holder**: tell them a file was blocked and why
* **Do not retry**: the same file will be blocked again
* **Do not disable Shield to bypass**: the file was blocked for a reason

***

## Manual Scanning

You can scan any file through Shield, even files that didn't come through AgentDrop:

<CodeGroup>
  ```python Python theme={null}
  # Scan a file from another source
  with open("untrusted-file.txt", "rb") as f:
      result = client.scan(f.read(), "untrusted-file.txt")

  print(f"Threat level: {result.threat_level}")
  print(f"Blocked: {result.blocked}")
  print(f"Intent score: {result.intent_score}")

  if result.injection_findings:
      print("Injection attempts detected:")
      for finding in result.injection_findings:
          print(f"  - {finding.description}")
  ```

  ```javascript Node.js theme={null}
  import fs from 'fs';

  const data = fs.readFileSync('untrusted-file.txt');
  const result = await client.scan(data, 'untrusted-file.txt');

  console.log(`Threat level: ${result.threatLevel}`);
  console.log(`Blocked: ${result.blocked}`);
  console.log(`Intent score: ${result.intentScore}`);

  if (result.injectionFindings.length > 0) {
    console.log('Injection attempts detected:');
    for (const finding of result.injectionFindings) {
      console.log(`  - ${finding.description}`);
    }
  }
  ```
</CodeGroup>

Use `client.scan()` to check files from:

* HTTP uploads from users or external services
* Message attachments from other agents
* Tool outputs that include file data
* Any untrusted file content your agent processes

<Note>
  `client.scan()` requires Shield to be enabled. If you initialized with `shield=False`, calling `scan()` raises `AgentDropError`.
</Note>

***

## Scan Results

Every scanned file returns a `ScanResult` object:

| Field                | Type    | Description                                                  |
| -------------------- | ------- | ------------------------------------------------------------ |
| `threat_level`       | `str`   | `none`, `low`, `medium`, `high`, or `critical`               |
| `blocked`            | `bool`  | Whether Shield blocked this file at the current strictness   |
| `intent_score`       | `float` | Internal score indicating likelihood of malicious intent     |
| `injection_findings` | `list`  | Individual findings with description and confidence          |
| `warnings`           | `list`  | Non-blocking warnings (e.g., unusual format, large metadata) |

```python theme={null}
result = client.scan(data, "report.pdf")

if result.threat_level == "none":
    print("Clean file")
elif result.blocked:
    print("Dangerous - do not process")
else:
    print(f"Warnings present: {result.warnings}")
    # File was allowed but proceed with caution
```

***

## Disabling Shield

You can disable Shield entirely, but this is not recommended. Without Shield, your agent is vulnerable to prompt injection attacks embedded in transferred files.

```python theme={null}
# Not recommended
client = AgentDrop(api_key="agd_...", shield=False)
```

When Shield is disabled:

* `client.download()` skips scanning entirely
* `client.scan()` raises `AgentDropError`
* `scan_result` in download results is `None`

***

## Error Reference

| Error                                            | Meaning                                                                          |
| ------------------------------------------------ | -------------------------------------------------------------------------------- |
| `ShieldBlockError`                               | A file was blocked due to detected threats. Check `e.scan_result` for details.   |
| `AgentDropError("Shield is disabled...")`        | You called `scan()` but initialized with `shield=False`.                         |
| `AgentDropError("Invalid shield_strictness...")` | Invalid strictness value. Use `permissive`, `standard`, `strict`, or `paranoid`. |
