Skip to main content

Dome Platform LangChain adapter — govern LangChain tools with Dome authorization

Project description

Dome LangChain Adapter

LangChain / LangGraph integration for the Dome Platform. It injects Dome identity and authorization into the seams of an existing LangChain app — it is additive, not a replacement for LangChain.

There are three surfaces, each opt-in:

Surface What it governs Key symbols
Governed tools tool calls DomeGovernedTool, govern_tools
Governed chat models LLM calls DomeChatOpenAI, DomeChatAnthropic, broker_chat, broker_chat_for
Compose primitives agent-to-agent handoffs & spawned fleets Gate, gate_edge, gate_command, session, mint_ephemeral, fleet_send, causal

Install

pip install dome-langchain                 # core adapter: tools + gates + spawn
pip install 'dome-langchain[openai]'       # + DomeChatOpenAI (langchain-openai)
pip install 'dome-langchain[anthropic]'    # + DomeChatAnthropic (langchain-anthropic)
pip install 'dome-langchain[langgraph]'    # + the LangGraph shims

The core install needs only langchain-core. The chat-model surfaces pull in a provider client; importing DomeChatOpenAI / DomeChatAnthropic without the matching extra raises an ImportError with the install hint.

1. Governed tools

DomeGovernedTool wraps any LangChain BaseTool. Before each execution it calls dome.DomeClient.check(); on deny it returns a denial message instead of running, and audit events are emitted automatically.

import dome
from dome_langchain import DomeGovernedTool, govern_tools

client = dome.DomeClient(dome.DomeConfig(base_url="https://api.domesystems.ai", token="dome_..."))
client.start()

governed = DomeGovernedTool(tool=search_tool, dome_client=client)
# or wrap several at once:
tools = govern_tools(client, [search_tool, db_tool, email_tool])

client.close()

2. Governed chat models

DomeChatOpenAI (the name mirrors its ChatOpenAI base; the older name DomeChatModel still works as an alias) is a ChatOpenAI subclass whose requests flow through the Dome Broker (the LLM gateway) under a specific agent's identity. The Broker authenticates the call as that agent, evaluates Cedar for the model action, audits it, then forwards to the upstream provider. Because it is a ChatOpenAI, streaming, tool-calling, and structured output work unchanged.

from dome_langchain import AgentIdentity, DomeChatOpenAI

# `for_agent` accepts any agent identity (anything with `token` +
# `gateway_endpoint`) — an `EphemeralAgent` from the spawn API, or an
# `AgentIdentity` for an ordinary long-lived agent:
llm = DomeChatOpenAI.for_agent(
    AgentIdentity(token="dome_...", gateway_endpoint="https://gw.example.com")
)
llm.invoke("Summarise this ticket.")          # called as that agent

# End-user delegation (act-as) — per call, or bound once:
llm.invoke("Summarise this ticket.", act_as=user)   # ActAs or OIDC-JWT string
per_user = llm.with_act_as(user)
per_user.invoke("Summarise this ticket.")

act_as is encoded into an X-Dome-Act-As header on that request only; the Broker exposes it to Cedar as principal.act_as and does not forward it upstream. broker_chat / broker_chat_for are factory shims that return a DomeChatOpenAI (with a construction-time act-as default).

For Claude-native features (prompt caching, extended thinking, citations) use the Anthropic ingress instead:

from dome_langchain import DomeChatAnthropic
llm = DomeChatAnthropic.for_agent(agent, model="claude-haiku-4-5")

3. Compose primitives (chains & spawn)

Gated handoffs

A Gate turns a Dome authorization check into a routing decision. gate_edge adapts it to a LangGraph conditional edge ((state) -> next_node); gate_command is the newer node-returns-Command idiom. Gate is also a Runnable guard: in an LCEL chain, gate | next forwards the payload on allow and raises GateDenied on deny. (Use gate.evaluate() when you want the GateDecision value instead.)

What a gate checks — and what it doesn't. A gate evaluates Cedar with the agent backing dome_client (typically the orchestrator/parent) as the principalnot the downstream node. The from_node/to_node labels and any extra context are application-asserted, not verified: a gate is a client-side routing decision, not a cryptographic boundary, so it governs hops only insofar as your nodes assert that context honestly. Verified call-chain identity is a planned platform feature (S.PRP.008).

from dome_langchain import gate_edge

g.add_conditional_edges(
    "classifier",
    gate_edge(dome_client=client, from_node="classifier",
              to_node="retriever", resource="chain.hop_allowed"),
    {"retriever": "retriever"},
)

On allow the hop proceeds; on deny it routes to an on_deny node or raises GateDenied.

Spawned ephemeral fleets

session + mint_ephemeral register real, short-lived child agents (each with its own Dome identity and token) and tear them down on exit. fleet_send fans them out across a LangGraph node via Send.

from dome_langchain import session, fleet_send, DomeChatOpenAI

with session(platform, parent_agent_id=parent.agent_id, gateway_endpoint=gw) as s:
    fleet = s.spawn(count=4, template="researcher")
    sends = fleet_send(node="research", fleet=fleet,
                       payload_fn=lambda agent, i: {"agent": agent, "task": tasks[i]})
    # inside the "research" node, each worker calls the LLM as itself:
    #   llm = DomeChatOpenAI.for_agent(state["agent"])
# session exit revokes + hard-deletes the whole fleet

mint_ephemeral / session require a dome.DomeAdminClient (a workspace-admin client), not the per-agent DomeClient.

Examples

Runnable end-to-end demos live in examples/ (chain, spawn, broker). They require a provisioned Dome workspace — see examples/README.md.

Documentation

License

Proprietary. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dome_langchain-0.1.0.tar.gz (58.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dome_langchain-0.1.0-py3-none-any.whl (27.3 kB view details)

Uploaded Python 3

File details

Details for the file dome_langchain-0.1.0.tar.gz.

File metadata

  • Download URL: dome_langchain-0.1.0.tar.gz
  • Upload date:
  • Size: 58.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dome_langchain-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0d98e7ba1ecf0fc2c65981c4f8a2f8c3faa0dd68a03156cae133a34b6544b678
MD5 3b96f505c84cad57f153eb8cd3b29230
BLAKE2b-256 679bb6a37f7b6747a3da4a39c9b9532b4c175c77cf88f9f5d67c8125b9b88d9b

See more details on using hashes here.

Provenance

The following attestation bundles were made for dome_langchain-0.1.0.tar.gz:

Publisher: release-langchain.yml on dome-systems/sdk-dome-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dome_langchain-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: dome_langchain-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 27.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dome_langchain-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0afa98ecb0373ab312bcd5117b4f65575bc65deb98df4a6f877e6283b997f274
MD5 95254e442401e7c07ce3e9ee350f3454
BLAKE2b-256 e2c839e96bbeeeb435f4b2af4e04c4d891dfac110fe9a5b2637eb4e33393b963

See more details on using hashes here.

Provenance

The following attestation bundles were made for dome_langchain-0.1.0-py3-none-any.whl:

Publisher: release-langchain.yml on dome-systems/sdk-dome-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page