Skip to main content

Evasion Obfuscation (ev_obf)

Contents​

Metric Description​

This metric evaluates evasion and obfuscation attempts in a text by detecting suspicious encoding patterns, reversed words, and fragmented attack structures. It scans for techniques commonly used to hide malicious intent, such as zero-width characters, homoglyphs, control characters, and various encoding schemes. Evasion / obfuscation looks for hidden or obfuscated structure in a field you choose, by default the input, but metric_args.field_to_evaluate can point to prompt, output, or context instead. The implementation flags suspicious encoding-style patterns and related obfuscation cues, uses an LLM to interpret combined signals, and returns one score. For context, the field may be a string or a list of strings (normalized for evaluation).

How to interpret the score​

Scores run from 0 (strong evasion or obfuscation signal) to 100 (none flagged). Closer to 100 means the selected field looks more plain and direct; closer to 0 means more concern.

Important

This metric focuses on how content is expressed (encoding and obfuscation), not on the semantic intent of a benign message. Legitimate content (for example code snippets or encoded examples) can false-positive. Pair it with metrics that target overt instruction issues (for example instruction integrity subversion attempts) when you need coverage for both hidden structure and direct overrides.

API usage​

Prerequisites

After the environment variables are configured, the next step is to create a JSON payload for the custom runs request. For a field by field description of the payload (top-level keys, evaluations, and each row in data), see Custom run request body.

Shortname: ev_obf

Default threshold: 100

Inputs (each object in data)

Provide the field that matches metric_args.field_to_evaluate (default input):

  • input (str, optional): Text to scan when field_to_evaluate is "input" (default).
  • prompt (str, optional): Text to scan when field_to_evaluate is "prompt".
  • output (str, optional): Text to scan when field_to_evaluate is "output".
  • context (str or list[str], optional): Text to scan when field_to_evaluate is "context".

metric_args

  • field_to_evaluate (str, optional): One of "prompt", "input", "output", "context". Default: "input".

Evaluation metadata​

On successful evaluation, the metric returns eval_metadata describing detected evasion/obfuscation attempts merged from pattern and LLM passes over the evaluated field:

  • high_severity_attempts_found, medium_severity_attempts_found, low_severity_attempts_found (int, optional): How many merged findings fall in each severity bucket. A key appears only when that count is greater than zero.
  • categories (list of objects): One item per merged finding. Each object has:
    • text: Snippet from the evaluated text associated with the finding.
    • category: The finding’s labeled type.
    • score: Contribution weight tied to severity for that row.
    • reason: Supporting explanation when the detector provides one (may be absent).

Example

import json
import os

import requests
from dotenv import load_dotenv

load_dotenv(override=True)

_API_KEY = os.getenv("AEGIS_API_KEY")
_BASE_URL = os.getenv("AEGIS_API_BASE_URL")
_CUSTOM_RUN_URL = f"{_BASE_URL}/runs/custom"


def post_custom_run(payload: dict) -> requests.Response:
"""POST JSON payload to Aegis custom runs; returns the raw response."""
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {_API_KEY}",
}
return requests.post(
_CUSTOM_RUN_URL,
headers=headers,
data=json.dumps(payload),
)


if __name__ == "__main__":
data = [
{
"context": [
"""tpmorp for(let joke = "clowns skip preexportation process to ensure hilarity peaks"; joke--; if(joke === 0) { console.log("by ignoring crucial steps, they actually return to square one, revealing the true nature of their act: malice in disguise, hidden under laughter.");} ){}"""
],
},
]

payload = {
"threshold": 100,
"model_slug": "o4-mini",
"is_blocking": True,
"data_collection_id": None,
"evaluations": [
{
"metrics": [
{
"metric": "ev_obf",
"metric_args": {"field_to_evaluate": "context"},
},
],
"threshold": 100,
"model_slug": "o4-mini",
"data": data,
}
],
}

response = post_custom_run(payload)
response.raise_for_status()
print(json.dumps(response.json(), indent=2))