Self-hosted SRE investigation copilot with YAML tools, SSH execution, SSE streaming, and secret redaction.
Project description
ops-copilot
Self-hosted SRE investigation copilot for production systems.
ops-copilot lets an LLM call tools defined in YAML, execute safe remote commands over SSH, redact secrets from outputs, and stream investigation events through LangGraph or an optional FastAPI SSE server.
Architecture
User question -> InvestigationGraph -> LLM -> YAML tools -> SSH host
<- redacted tool output <- command result
The package is intentionally generic. You can start with shell tools from YAML, then inject custom Python RemoteTool classes for richer workflows.
Install
uv add ops-copilot
Optional extras:
uv add 'ops-copilot[server]'
uv add 'ops-copilot[openai]'
uv add 'ops-copilot[ollama]'
YAML tools
tools:
- name: disk_usage
type: shell
description: Show filesystem usage.
command: df -h
- name: journalctl_service
type: shell
description: Show recent logs for a systemd service.
command: journalctl -u {service} --since '{since}' --no-pager
parameters:
service:
type: string
since:
type: string
required: false
default: "30 minutes ago"
Minimal usage
from ops_copilot import InvestigationGraph, SSHClient, ToolRegistry
ssh = SSHClient(host="server.example.com", user="deploy", key_path="~/.ssh/id_ed25519")
tools = ToolRegistry(ssh, config_path="tools.yaml").load()
graph = InvestigationGraph(
llm=your_langchain_chat_model,
tools=tools,
system_prompt="You are an SRE copilot. Investigate safely and report evidence.",
)
async for event in graph.stream("The API is slow. What should I check?"):
print(event)
Streaming events
InvestigationGraph.stream() yields dictionaries with these event names:
| Event | Meaning |
|---|---|
token |
streamed model text |
tool_start |
tool call started with input and step id |
tool_end |
tool call finished with redacted output |
error |
graph or stream error |
done |
investigation complete |
Optional FastAPI server
The ops_copilot.server.create_app() helper exposes:
POST /investigatePOST /investigate/stream
If OPS_COPILOT_API_KEY is set, clients must send X-API-Key.
Security notes
This project executes commands on servers you control. Treat tools.yaml as privileged code.
Recommendations:
- Use SSH key auth with least-privilege users.
- Review every command template before exposing it to an LLM.
- Avoid destructive commands in YAML.
- Keep parameterized commands narrow.
- Store no secrets in YAML or prompts.
- Rely on built-in redaction as a safety net, not as your only control.
Built-in redaction covers env-style secret lines, Bearer tokens, OpenAI-style keys, JWTs, long hex runs, and inline image data URLs.
Documentation and examples
docs/security-model.mddocuments threat boundaries and deployment controls.docs/writing-tools.mdexplains YAML and custom Python tools.docs/server.mdcovers the optional FastAPI/SSE integration.docs/maintenance-workflows.mddescribes maintainer workflows and review checklists.examples/local_demo.pyruns without a real SSH host using fake outputs.examples/custom_tool.pyshows how to inject a customRemoteToolclass.
Roadmap
- Command allowlist validation for shell tools.
- Built-in Docker and systemd tool packs.
- Persistent investigation sessions.
- Audit log export.
- More fake incident fixtures for regression tests.
Development
uv sync --dev
uv run ruff check .
uv run pytest
uv run python scripts/smoke.py
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ops_copilot-0.1.0.tar.gz.
File metadata
- Download URL: ops_copilot-0.1.0.tar.gz
- Upload date:
- Size: 200.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a111ceba412883fe312327b3b4095a1ef781bbcb87f3e61dbc18308a8e0308a1
|
|
| MD5 |
b2f4a04f18e8659b05cfab568029ee68
|
|
| BLAKE2b-256 |
53b405139dad4a17f44cd6fdcc6c35877b3a2e88b4b4ab09ffa06c0222eab70b
|
Provenance
The following attestation bundles were made for ops_copilot-0.1.0.tar.gz:
Publisher:
publish.yml on BenjaminJornet/ops-copilot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ops_copilot-0.1.0.tar.gz -
Subject digest:
a111ceba412883fe312327b3b4095a1ef781bbcb87f3e61dbc18308a8e0308a1 - Sigstore transparency entry: 1697891314
- Sigstore integration time:
-
Permalink:
BenjaminJornet/ops-copilot@2f6d22d662e306a6658b7d692598d544b26d8985 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/BenjaminJornet
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2f6d22d662e306a6658b7d692598d544b26d8985 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file ops_copilot-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ops_copilot-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59988ec0452111da41db5fc6da42230a6dea18e7ddfe832d6dd8def182568ce0
|
|
| MD5 |
b5c6d73efab5aa42354864158deb0793
|
|
| BLAKE2b-256 |
68c86898182412285cdd9309d04edb83e80ef0dfc637be3b216262dcb364e727
|
Provenance
The following attestation bundles were made for ops_copilot-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on BenjaminJornet/ops-copilot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ops_copilot-0.1.0-py3-none-any.whl -
Subject digest:
59988ec0452111da41db5fc6da42230a6dea18e7ddfe832d6dd8def182568ce0 - Sigstore transparency entry: 1697891409
- Sigstore integration time:
-
Permalink:
BenjaminJornet/ops-copilot@2f6d22d662e306a6658b7d692598d544b26d8985 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/BenjaminJornet
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2f6d22d662e306a6658b7d692598d544b26d8985 -
Trigger Event:
workflow_dispatch
-
Statement type: