Skip to content

Integrations

An integration connects a Tulip agent to a system it acts on — messaging (Slack), identity (Okta, Auth0, Entra), compute, and security operations (Splunk log search, CrowdStrike endpoint control, and more). The security catalog was built and hardened first; the pattern is general. Some integrations only read evidence (search logs, look up a reputation, pull cloud posture); the higher-stakes ones let the agent act — contain a host, disable an account. Tulip treats those two very differently.

Tulip follows a core + community split:

  • tulip-agents (core) ships the agent engine, the admission gate (admit() / approve() / the tamper-evident audit trail), the grounding contracts (Evidence / ground_finding), the domain ports (LogSource, EndpointSource, IdentitySource, …), the SecurityAdapter protocol, and bundled offline reference adapters so the SDK runs standalone with no credentials.
  • tulip-integrations (community) ships the maintained, vendor-specific integrations. It depends on core (one-way — core never imports it).

Reads are evidence; writes are governed

This is the point of integrating through Tulip rather than handing an agent a raw vendor SDK. A read returns evidence, and a finding only ships if it clears GSAR grounding — Tulip's evidence check: a claim must be backed by tool output, otherwise the agent abstains. A write is a real action, so it doesn't run on the model's say-so — it runs through the admission chain policy → approval → admission → audit. You wrap the side effect in an Action; the gate runs it only if a ControlPolicy (blast radius, verification score, require_human_for={"production"}) allows — otherwise it raises AdmissionError. Wire an AuditTrail into admit() and every decision (run or held) is recorded to its hash chain:

from tulip.control import Action, ControlPolicy, AuditTrail, admit, AdmissionError

# A write is an Action + the call that performs it. Under the default policy a
# production action is HELD for a human — so this raises AdmissionError instead
# of running; pass a trail and the decision is recorded either way.
trail = AuditTrail()
contain = Action(name="endpoint.isolate", asset="prod-db-01", blast_radius=50,
                 environment="production", kind="containment")
await admit(contain, lambda: ctx.endpoint.isolate("prod-db-01"),
            policy=ControlPolicy(), trail=trail)
# → AdmissionError: REQUIRE_HUMAN — a prompt injection can't make this run on its own.

An injected prompt can change what the model decides, but it can't make the action run — that's the policy's call, not the model's. (ctx.actions.execute runs the same gate.) The integrations that actually take action (writes): CrowdStrike (contain a host), Okta / Auth0 / Entra ID (disable an account), Cortex XSOAR (close an incident), and Slack (post to a channel). The rest are read-only evidence sources.

Two ways to use an integration

1. As a domain provider (recommended) — inject it into a SecurityContext and your investigation code stays vendor-agnostic. Swap Okta for Auth0 by changing one line:

import asyncio
from tulip.security import SecurityContext
from tulip_integrations.identity.auth0 import Auth0Identity
from tulip_integrations.threat_intel.virustotal import VirusTotalIntel


async def main():
    ctx = SecurityContext(identity=Auth0Identity(), threat_intel=VirusTotalIntel())
    await ctx.identity.get_user("[email protected]")  # read: hits the real Auth0 Management API
    # a write (ctx.identity.disable) goes through ctx.actions.execute — gated
    # (disable is a simulated offline stub today; risk reads are offline-sample-only)


asyncio.run(main())

2. As agent tools — merge a vendor's @tools into the toolset for an autonomous agent:

from tulip.agent import Agent
from tulip.security import security_toolset
from tulip_integrations.siem.splunk import splunk_siem_tool

agent = Agent(
    model="anthropic:claude-sonnet-4-6",
    tools=security_toolset(siem=False, extra=[splunk_siem_tool]),
    system_prompt="You are a SOC analyst. Cite the evidence behind every verdict.",
)

Either way, the same two rules hold: a finding routes through GSAR ground_finding so an ungrounded result abstains, and a write routes through the admission gate so it only runs gated and audited — never on best intentions. (All integrations bring their own credentials from the environment and return JSON.)

Governed MCP — hand the capability, not the authority

Tulip ships an MCP server, so you can expose a tool to another agent — a Claude or GPT client, a separate orchestrator — over the Model Context Protocol. What makes this safe: the admission gate lives inside the action, not the transport. Build the tool so its body routes the write through admit() / ctx.actions.execute, and a remote agent gets the capability to ask without the authority to skip your ControlPolicy — the write still clears policy (and, in production, a human) and still lands in your audit trail.

What each integration does

General-purpose systems first — messaging, identity, compute — then the security-operations block. Domain shorthand: SIEM — log search platforms like Splunk; EDR — endpoint control tools like CrowdStrike; AI-SPM — AI Security Posture Management.

Integration Domain What it does Provider Install
Slack notify Post a finding / message to a channel (write — human handoff; live-only) (tools) notify-slack
Okta identity Look up a user (live), sign-ins (live), risk (offline sample), disable an account (write — simulated offline stub) OktaIdentity identity-okta
Auth0 identity Look up a user (live), sign-ins (live), risk (offline sample), disable an account (write — simulated offline stub) Auth0Identity identity-auth0
Microsoft Entra ID identity User + sign-ins (live), risk + impossible-travel → grounded finding (offline sample), disable an account (write — simulated offline stub) EntraIdentity identity-entra
RunPod / Lambda compute (advanced) Specialized: deploy a GPU endpoint to fingerprint-probe a model you operate (probe) compute-runpod / compute-lambda
AWS cloud Read-only cloud-posture evidence (in core) (core) tulip-agents[aws]
Splunk SIEM Search logs/events with an SPL query SplunkLogs siem-splunk
CrowdStrike Falcon EDR Host device record + open detections (offline sample is a fuller forensic timeline), network-contain a host (write) CrowdStrikeEndpoint edr-crowdstrike
Cortex XSOAR SOAR Read incidents, search, close an incident (write) + ground incidents to findings CortexXSOAR soar-cortex-xsoar
VirusTotal threat-intel Reputation for an IP, domain, or file hash VirusTotalIntel threat-intel-virustotal
Wiz AI-SPM AI-BOM inventory + posture issues → grounded findings (tools) wiz-aispm
OSV supply-chain Dependency vulnerability lookup (in core) (core) built-in

Build your own integration · SecurityContext