Skip to content

DOCUMENTATION

Sentinely Docs

Everything you need to protect your AI agents from prompt injection, memory poisoning, and drift.

Quick Start

Protect your AI agent in 3 lines of code. No configuration required to get started.

1

Install the package

pip install sentinely
2

Wrap your agent

from sentinely import protect

# Wrap any AI agent in one line
agent = protect(
    your_agent,
    task="Summarize quarterly reports"
)
3

Add your API key

# .env
SENTINELY_API_KEY=sntnl_live_...

THAT'S IT

Your agent is now protected. Sentinely monitors every action, blocks attacks automatically, and streams events to your dashboard in real time. No additional code required.

Installation

Python 3.10+ or Node.js 18+.

pip install sentinely

Configuration

Sentinely is configured via environment variables. Create a .env file in your project root.

# Required — get this from your dashboard
SENTINELY_API_KEY=sntnl_live_...

# Optional — defaults shown
SENTINELY_ENV=production
VARIABLEREQUIREDDEFAULTDESCRIPTION
SENTINELY_API_KEYYesYour API key. Sign up free at sentinely.ai/signup.
SENTINELY_ENVNodevelopmentSet to production to enable event forwarding.

Never commit your SENTINELY_API_KEY to version control. Add .env to your .gitignore file.

protect()

The single entry-point for all Sentinely protection. Returns a ProtectedAgent that wraps your agent.

from sentinely import protect

protected = protect(
    agent,                  # Any agent object
    task,                   # str  — the agent's mission / system prompt
    policy="strict",        # "strict" | "monitor" | "permissive"
    agent_id=None,          # Optional str — stable ID across restarts
    org_id=None,            # Optional str — your organisation slug
    tracker=None,           # Optional MultiAgentTracker
)

PARAMETERS

PARAMETERTYPEREQUIREDDESCRIPTION
agentobjectYesAny agent that exposes .run(), .invoke(), .ainvoke(), or __call__().
taskstrYesThe agent's purpose / system prompt. Used as the baseline for drift detection.
policystrNo"strict" blocks dangerous actions. "monitor" logs only. "permissive" allows with warnings.
agent_idstrNoStable identifier. Defaults to a random hex ID. Use a fixed value to correlate sessions.
org_idstrNoOrganisation slug. Defaults to "local". Visible in the dashboard under your org.
trackerMultiAgentTrackerNoPass a tracker to enable inter-agent drift monitoring across agent boundaries.

RETURNS

A ProtectedAgent instance that is a transparent proxy to your original agent. It exposes the same interface:

.invoke(input)Async: scan input → run agent → return result
.ainvoke(input)Async version of .invoke()
.run(input)Sync wrapper. Runs the async pipeline via event loop
.__call__(input)Callable shorthand. Delegates to .invoke()
.score_action(tool, params)Score a pending tool call. Call from your tool hooks
.memoryAccess the MemoryFirewall for poisoning detection
.get_audit_log()Return all events buffered locally this session

EXAMPLE

import asyncio
from sentinely import protect

agent = protect(
    my_agent,
    task="Analyse customer churn data. Read-only. No external API calls.",
    policy="strict",
    agent_id="churn-analyst-v2",
)

# Synchronous
result = agent.run("Analyse churn for Q3")

# Async
result = await agent.ainvoke("Analyse churn for Q3")

# As callable
result = agent("Analyse churn for Q3")

COMING SOON

Native Python adapters for CrewAI, AutoGen and LlamaIndex. Sentinely will plug directly into your existing agent framework with zero code changes.

v0.2.0

Policy Modes

Choose the enforcement level that matches your deployment stage. You can change the policy at any time without restarting.

🛡️STRICT

Blocks any action that scores above the risk threshold. Raises SentinelyBlockedError so you can handle it gracefully. Recommended for production.

policy="strict"
👁️MONITOR

Logs and scores every action but never blocks execution. Use during development or when rolling out Sentinely to an existing agent without changing its behaviour.

policy="monitor"
PERMISSIVE

Allows all actions but attaches risk scores and reasons to each event. Useful for research, red-teaming, or building a baseline before switching to strict.

policy="permissive"

HANDLING BLOCKS

from sentinely.exceptions import SentinelyBlockedError

try:
    result = agent.run(user_input)
except SentinelyBlockedError as e:
    print(f"Blocked: {e.reason}")
    print(f"Risk score: {e.risk_score}")
    print(f"Attack type: {e.attack_type}")
    # Return a safe fallback response to the user

Framework Examples

Sentinely works with any Python or Node.js AI agent framework. Select your framework below.

from openai import OpenAI
from sentinely import protect

client = OpenAI()

class MyAgent:
    def run(self, prompt):
        response = client.chat.completions.create(
            model="gpt-4",
            messages=[{"role": "user", "content": prompt}]
        )
        return response.choices[0].message.content

agent = MyAgent()
agent = protect(
    agent,
    task="Answer customer support questions about billing",
    policy="strict",
    agent_id="openai-support-agent"
)

result = agent.run("How do I update my payment method?")
Coming in v0.2.0:CrewAIAutoGenLlamaIndex

LangChain Integration

Sentinely integrates natively with LangChain. Choose the approach that fits your architecture.

INSTALLATION

pip install sentinely[langchain]

THREE APPROACHES

SentinelyToolPer-tool

Wrap individual tools. Blocked calls return a safe string instead of throwing. Great for graceful degradation.

Callback HandlerAgent-wide

Attach to any LangChain agent executor. Throws SentinelyBlockedError on block, halting the agent.

protectLangChain()Recommended

One-liner convenience wrapper. Mirrors the Python protect_langchain() API. Installs the callback and returns the agent.

CODE EXAMPLES

from sentinely import protect
from sentinely.adapters.langchain import (
    SentinelyTool, SentinelyCallbackHandler, protect_langchain,
)

# Option 1 — Tool wrapper (per-tool protection)
agent = protect(my_agent, task="Summarise quarterly reports", policy="strict")
safe_tool = SentinelyTool(your_tool, agent)

# Option 2 — Agent-wide callback
agent = protect(my_agent, task="Summarise quarterly reports", policy="strict", agent_id="my-agent")
handler = SentinelyCallbackHandler(agent)
executor = AgentExecutor(agent=..., tools=tools, callbacks=[handler])

# Option 3 — Convenience wrapper (recommended)
executor = protect_langchain(
    AgentExecutor(agent=..., tools=tools),
    task="Summarise quarterly reports",
    policy="strict",
    agent_id="my-agent",
)
ℹ️

LangChain is an optional dependency. Python: pip install sentinely[langchain] installs the extras. Node.js: install langchain and @langchain/core separately. They are peer dependencies.

Multi-Agent Tracking

Track behavioral drift across every agent in a pipeline. Detect inter-agent manipulation before it spreads.

WHAT IT DETECTS

Authority CreepGradual

Messages that slowly expand an agent's permissions or role beyond what was originally authorised.

Identity SwapHigh Severity

Instructions that attempt to redefine the agent's identity, persona, or core behavioral constraints.

Salami-SlicingCumulative

Many individually low-risk messages that together shift the agent's behavior significantly over time.

Permission ExpansionEscalation

Requests for capabilities, access, or actions that fall outside the agent's original task scope.

CODE EXAMPLE

import asyncio
from sentinely import protect, MultiAgentTracker
from sentinely.multi_agent import AgentMessage

tracker = MultiAgentTracker()

# Register each agent (async)
await tracker.register_agent(
    agent_id='agent-1',
    session_id='session-abc',
    system_prompt='Summarise financial reports',
)
await tracker.register_agent(
    agent_id='agent-2',
    session_id='session-abc',
    system_prompt='Send email summaries',
)

# Pass tracker into protect()
agent1 = protect(
    my_agent1,
    task='Summarise financial reports',
    agent_id='agent-1',
    tracker=tracker,
)

# Check drift scores (synchronous)
scores = tracker.get_all_drift_scores()
# {'agent-1': {'drift_score': 0, 'risk_level': 'stable'}}

DRIFT RISK LEVELS

SAFE

Python: drift_score < 20

Node: driftScore < 20

Agent is behaving within its original constraints. No action required.

ELEVATED

Python: 20 ≤ drift_score < 40

Node: 20 ≤ driftScore < 40

Suspicious patterns detected. Review recent inter-agent messages in the dashboard.

HIGH

Python: 40 ≤ drift_score < 60

Node: 40 ≤ driftScore < 60

Significant drift detected. Monitor closely and consider pausing the agent for review.

COMPROMISED

Python: drift_score ≥ 60

Node: driftScore ≥ 60

Agent is compromised. All further messages to this agent are blocked. Reset the fingerprint to resume.

ℹ️

Manipulation events appear in the dashboard with attack_type: 'manipulation'. Python field names use snake_case (drift_score, risk_level). Node.js uses camelCase (driftScore, riskLevel).

Understanding Alerts

Every action your agent takes gets a risk score from 0–100. Here is how to read what Sentinely is telling you.

RISK SCORE

0 – 49
ALLOWED

Action is within normal operating bounds. Agent is behaving as expected.

50 – 79
FLAGGED

Action looks suspicious. Logged and surfaced in your dashboard. Agent continues but you should review.

80 – 100
BLOCKED

Action is blocked. Agent receives an error. Slack/email alerts fire. Item appears in Quarantine if memory-related.

ATTACK TYPES

💉Prompt Injection

Malicious instructions embedded in external content trying to hijack the agent's behavior. Most common attack vector.

🧠Memory Poisoning

Attempts to write malicious instructions into the agent's long-term memory to influence future sessions.

🧭Intent Drift

Agent's actions gradually deviate from its original task. Often a sign of a slow multi-step manipulation.

🕸Multi-Agent Manipulation

One agent attempts to manipulate another in a multi-agent pipeline. Detected by behavioral fingerprinting.

DRIFT SCORE

0 – 19SAFEAgent is behaving within its original constraints. No action required.
20 – 39ELEVATEDSuspicious patterns detected. Review recent inter-agent messages in the dashboard.
40 – 59HIGHSignificant drift detected. Monitor closely and consider pausing the agent for review.
60 – 100COMPROMISEDAgent is compromised. All further messages to this agent are blocked. Reset the fingerprint to resume.

Framework Guides

Complete, copy-pasteable integration examples for popular AI agent frameworks.

LANGCHAIN (PYTHON)

Wrap a LangChain agent with tool calling. Sentinely monitors every tool invocation.

pip install sentinely[langchain] langchain langchain-openai
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from sentinely.adapters.langchain import protect_langchain

@tool
def lookup_order(order_id: str) -> str:
    """Look up an order by ID and return its status."""
    return f"Order {order_id}: shipped, arriving Thursday"

@tool
def send_email(to: str, subject: str, body: str) -> str:
    """Send an email to a customer."""
    return f"Email sent to {to}"

llm = ChatOpenAI(model="gpt-4o", temperature=0)
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a customer support agent. Help with orders."),
    ("human", "{input}"),
    MessagesPlaceholder("agent_scratchpad"),
])

agent = create_openai_tools_agent(llm, [lookup_order, send_email], prompt)
executor = AgentExecutor(agent=agent, tools=[lookup_order, send_email])

# Wrap with Sentinely — one line
executor = protect_langchain(
    executor,
    task="Answer customer support questions about orders",
    policy="strict",
    agent_id="support-agent",
)

result = executor.invoke({"input": "Where is order #1234?"})

CREWAI

Add Sentinely to a CrewAI crew with multiple agents. Each agent gets its own behavioral fingerprint.

pip install sentinely crewai crewai-tools
from crewai import Agent, Task, Crew
from sentinely import protect

researcher = Agent(
    role="Senior Research Analyst",
    goal="Find and summarize market trends",
    backstory="You are an expert market researcher.",
    verbose=True,
)

writer = Agent(
    role="Technical Writer",
    goal="Write clear reports from research findings",
    backstory="You write concise, accurate technical reports.",
    verbose=True,
)

# Wrap each agent independently
researcher = protect(
    researcher,
    task="Research market trends from public data only",
    policy="strict",
    agent_id="crewai-researcher",
)

writer = protect(
    writer,
    task="Write reports from provided research. No external access.",
    policy="strict",
    agent_id="crewai-writer",
)

research_task = Task(
    description="Analyze Q1 2026 AI infrastructure trends",
    expected_output="A bullet-point summary of top 5 trends",
    agent=researcher,
)

write_task = Task(
    description="Write a 1-page report from the research summary",
    expected_output="A polished report in markdown",
    agent=writer,
)

crew = Crew(
    agents=[researcher, writer],
    tasks=[research_task, write_task],
    verbose=True,
)

result = crew.kickoff()

VERCEL AI SDK (NODE.JS)

Protect a Vercel AI SDK route handler. Sentinely runs as middleware on every streamed response.

npm install sentinely ai @ai-sdk/openai
// app/api/chat/route.ts
import { streamText } from 'ai'
import { openai } from '@ai-sdk/openai'
import { sentinelyMiddleware } from 'sentinely/adapters/vercel'

export async function POST(req: Request) {
  const { messages } = await req.json()

  const result = streamText({
    model: openai('gpt-4o'),
    system: 'You are a helpful assistant for our SaaS product.',
    messages,
    experimental_transform: sentinelyMiddleware({
      task: 'Answer product questions. No competitor comparisons.',
      policy: 'strict',
      agentId: 'vercel-chat-agent',
    }).transform(),
  })

  return result.toDataStreamResponse()
}

OPENAI AGENTS SDK (PYTHON)

Wrap an OpenAI Agents SDK agent. Sentinely intercepts tool calls and function outputs.

pip install sentinely openai-agents
from agents import Agent, Runner, function_tool
from sentinely import protect

@function_tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"72°F and sunny in {city}"

@function_tool
def book_flight(origin: str, dest: str, date: str) -> str:
    """Book a flight between two cities."""
    return f"Flight booked: {origin} → {dest} on {date}"

agent = Agent(
    name="travel-assistant",
    instructions="You help users plan trips. Only book flights "
                 "the user explicitly requests.",
    tools=[get_weather, book_flight],
)

# Wrap with Sentinely
agent = protect(
    agent,
    task="Help users plan trips. Only book when explicitly asked.",
    policy="strict",
    agent_id="openai-travel-agent",
)

result = Runner.run_sync(agent, "What's the weather in Tokyo?")

RAW PYTHON

The minimal example. Works with any Python object that has a callable method.

pip install sentinely
from sentinely import protect

class MyAgent:
    def run(self, prompt: str) -> str:
        # Your agent logic — call an LLM, run tools, etc.
        return f"Processed: {prompt}"

agent = MyAgent()

# Wrap with Sentinely
agent = protect(
    agent,
    task="Summarize customer feedback. Read-only, no external calls.",
    policy="strict",
    agent_id="feedback-summarizer",
)

# Use as normal — Sentinely monitors .run(), .invoke(), .__call__()
result = agent.run("Summarize last week's support tickets")

RAW NODE.JS

Same minimal pattern for Node.js. Wraps any object or function.

npm install sentinely
import { protect } from 'sentinely'

class MyAgent {
  async run(prompt) {
    // Your agent logic — call an LLM, run tools, etc.
    return `Processed: ${prompt}`
  }
}

const agent = protect(new MyAgent(), {
  task: 'Summarize customer feedback. Read-only, no external calls.',
  policy: 'strict',
  agentId: 'feedback-summarizer',
})

// Use as normal — Sentinely monitors .run(), .invoke(), .call()
const result = await agent.run('Summarize last week\'s support tickets')

CI/CD Security Scanner

Scan your agent system prompts for vulnerabilities before they reach production. The Sentinely CLI finds prompts in your source code and scores them automatically. It ships inside the sentinely npm package, no separate install needed.

Quick Start

npx sentinely scan ./src --api-key $SENTINELY_API_KEY

Options

FlagDescription
--threshold <number>Minimum score to pass (default: 60)
--api-key <key>Sentinely API key (or set SENTINELY_API_KEY env var)
--format <text|json|github>Output format (default: text)
--fail-on <critical|high|medium|any>Severity filter (default: any)
--config <path>Config file path (default: .sentinely.yml)

CI/CD Examples

GitHub Actions

name: Agent Security Scan
on: [pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Sentinely Security Scan
        run: npx sentinely scan ./src --api-key ${{ secrets.SENTINELY_API_KEY }} --format github

GitLab CI

sentinely-scan:
  script:
    - npx sentinely scan ./src --api-key $SENTINELY_API_KEY

Any CI system

npx sentinely scan ./src --api-key $SENTINELY_API_KEY

Config File

# .sentinely.yml
threshold: 70
fail_on: high
include:
  - "src/**/*.py"
  - "src/**/*.ts"
exclude:
  - "tests/**"

No signup needed for up to 3 scans per day. Create a free account at sentinely.ai for unlimited scans.

Supply Chain Monitor

Detect when external tools change their response schemas, spike in latency, or start returning errors. Sentinely builds a behavioral baseline for each tool and alerts on deviations.

After each external tool call, report the response back to Sentinely. The first 20 calls build a baseline (schema shape, latency distribution, error rate). After locking, any deviation triggers an anomaly alert in the dashboard.

# After calling an external tool:
result = await external_api.call(params)
agent.report_tool_response(
    tool_name="lookup_user",
    response_data=result,
    latency_ms=elapsed_ms,
    is_error=False,
)

View tool health and anomalies in the dashboard at /tools. Anomalies include schema changes (new/removed fields), latency spikes (>3x p95), and error spikes.

Threat Intelligence

When you confirm an attack in the dashboard, the attack pattern is anonymized and shared across all Sentinely customers. Your agents benefit from attacks detected at other organizations without exposing any private data.

How it works: Label any alert as “Confirmed Attack” in the dashboard. Sentinely extracts the attack pattern, strips all org-specific data (emails, URLs, agent IDs), and adds it to the shared signature database.

SDK integration: The SignatureCache refreshes every 6 hours automatically. No code changes needed. New patterns are applied to scoring immediately.

Dashboard: The overview page shows active signature count. Alerts matched by collective intelligence display a “Detected by Collective Intelligence” badge.

Red Team

Automated adversarial testing. Generates tailored attack vectors against your agent's system prompt and scores each one through the Sentinely pipeline. Runs against the scoring engine, not your live agent. Safe to run anytime.

Click Run Now in the dashboard at /redteam. Sentinely generates 30+ static attack templates (injection, drift, memory poisoning, escalation, multi-agent) plus LLM-adaptive payloads tailored to your specific system prompt.

Each attack vector is scored through the full pipeline. The report shows detected vs bypassed vectors with actionable remediation for each bypass.

Schedule weekly runs to continuously test your defenses as your prompts evolve. Available on all plans (free: 1/month, starter: 4/month, pro+: unlimited).

Behavioral DNA

Builds a unique behavioral profile for each agent: tool call sequences, parameter patterns, and active hours. After the baseline locks, any deviation from the established DNA triggers drift detection.

No code changes needed. The SDK automatically tracks 2-gram tool sequences, parameter distributions (file paths, email domains, URL patterns), and hourly UTC activity. DNA locks after 100+ actions across 5+ sessions over 7+ days.

Once locked, a deviation score (0-100) is computed for each action: novel tool sequences (+30), unknown parameter targets (+20-25), unusual hours (+15). High deviations generate drift events in the timeline.

View the DNA profile in the Behavioral DNA tab in the agent detail view at /agents.

Certification

Issue verifiable security certifications for agents that pass continuous monitoring. Each cert includes a public verification URL and an embeddable badge.

Criteria: 30+ days monitored, no critical alerts in 30 days, quarantine clear, scan score ≥ 70, red team score ≥ 80. Certifications are valid for 30 days and auto-revoke if criteria are no longer met.

Issue and manage certifications at /certifications. Each cert includes a public URL at sentinely.ai/cert/[token] that anyone can visit to verify the agent’s security status.

Available on paid plans only (starter: 1 active cert, pro+: unlimited).

FAQ

Common questions about Sentinely.

⬡ SENTINELY
© 2026 Sentinely. All rights reserved.