{"id":50469668,"url":"https://github.com/braedonsaunders/steward","last_synced_at":"2026-06-01T09:32:41.304Z","repository":{"id":344835104,"uuid":"1172177606","full_name":"braedonsaunders/steward","owner":"braedonsaunders","description":"Your network's first AI employee. Self-hosted autonomous agent that discovers, monitors, and manages your entire infrastructure — no IT department needed.","archived":false,"fork":false,"pushed_at":"2026-03-16T19:06:51.000Z","size":6159,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-17T02:00:38.203Z","etag":null,"topics":["agentic-ai","ai-agents","automation","autonomous-agents","chatbot","device-management","devops","docker","homelab","infrastructure-management","llm","monitoring","network-automation","network-discovery","network-monitoring","nextjs","self-hosted","selfhosted","sysadmin","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/braedonsaunders.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-04T02:45:30.000Z","updated_at":"2026-03-16T19:07:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"9904f986-521c-4fc2-bc82-47bcb5b8c11e","html_url":"https://github.com/braedonsaunders/steward","commit_stats":null,"previous_names":["braedonsaunders/steward"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/braedonsaunders/steward","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/braedonsaunders%2Fsteward","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/braedonsaunders%2Fsteward/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/braedonsaunders%2Fsteward/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/braedonsaunders%2Fsteward/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/braedonsaunders","download_url":"https://codeload.github.com/braedonsaunders/steward/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/braedonsaunders%2Fsteward/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33769491,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-ai","ai-agents","automation","autonomous-agents","chatbot","device-management","devops","docker","homelab","infrastructure-management","llm","monitoring","network-automation","network-discovery","network-monitoring","nextjs","self-hosted","selfhosted","sysadmin","typescript"],"created_at":"2026-06-01T09:32:39.604Z","updated_at":"2026-06-01T09:32:41.296Z","avatar_url":"https://github.com/braedonsaunders.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"steward.png\" alt=\"Steward\" width=\"100%\" /\u003e\n  \u003ch1\u003eSteward\u003c/h1\u003e\n  \u003cp\u003e\u003cstrong\u003eYour network's first employee.\u003c/strong\u003e\u003c/p\u003e\n  \u003cp\u003e\n    \u003ca href=\"#quickstart\"\u003e\u003cstrong\u003eQuickstart\u003c/strong\u003e\u003c/a\u003e\n    |\n    \u003ca href=\"#screenshots\"\u003e\u003cstrong\u003eScreenshots\u003c/strong\u003e\u003c/a\u003e\n    |\n    \u003ca href=\"#documentation\"\u003e\u003cstrong\u003eDocumentation\u003c/strong\u003e\u003c/a\u003e\n    |\n    \u003ca href=\"#what-this-repo-actually-ships\"\u003e\u003cstrong\u003eWhat This Repo Ships\u003c/strong\u003e\u003c/a\u003e\n    |\n    \u003ca href=\"#api-surface\"\u003e\u003cstrong\u003eAPI Surface\u003c/strong\u003e\u003c/a\u003e\n  \u003c/p\u003e\n  \u003cp\u003e\n    \u003cimg alt=\"Self-hosted\" src=\"https://img.shields.io/badge/self--hosted-yes-0f766e?style=for-the-badge\" /\u003e\n    \u003cimg alt=\"SQLite-backed state\" src=\"https://img.shields.io/badge/state-SQLite-1d4ed8?style=for-the-badge\" /\u003e\n    \u003cimg alt=\"RBAC\" src=\"https://img.shields.io/badge/access-RBAC%20%2B%20SSO-7c3aed?style=for-the-badge\" /\u003e\n    \u003cimg alt=\"Remote access\" src=\"https://img.shields.io/badge/remote-RDP%20%2F%20VNC%20%2F%20terminal-0f172a?style=for-the-badge\" /\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/braedonsaunders/codeflow\"\u003e\u003cimg src=\".github/codeflow-card.svg\" alt=\"Steward codebase stats — powered by codeflow\" width=\"100%\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nSteward is a self-hosted IT operations control plane for small networks: a local-first system with discovery, persistent state, graph-backed inventory, chat over live infrastructure context, policy-gated remediation, secure credential storage, device onboarding, widgets, automations, and operator access control.\n\nThe current repo also includes a first-class autonomy layer:\n\n- `missions` for durable goals Steward owns over time\n- `subagents` for domain-specific operational ownership\n- `investigations` for persistent follow-up instead of one-shot alerts\n- `packs` for installable operational knowledge\n- a Telegram-first `gateway` for briefings, approvals, and operator presence\n- mission-thread chat sessions that bind Telegram threads, chat history, and mission ownership together\n\nCurrent release highlights:\n\n- DB-backed configuration with no product env-var drift\n- durable job control plane for monitoring, remediation, and notifications\n- graph projections with temporal node and edge history\n- time-series persistence for latency and assurance evidence\n- section-based live state streaming instead of full-state SSE snapshots\n\n## Documentation\n\n- [Architecture](./docs/architecture.md)\n- [Operator Guide](./docs/operator-guide.md)\n- [Security](./docs/security.md)\n- [API Guide](./docs/api.md)\n- [Packs SDK](./docs/packs-sdk.md)\n\n## Screenshots\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"./docs/screenshots/inbox-overview.png\" alt=\"Steward dashboard and inbox overview\" /\u003e\n      \u003cp\u003e\u003cstrong\u003eInbox and morning briefing\u003c/strong\u003e\u003cbr /\u003eCritical issues, approvals, recommendations, and operator context in one surface.\u003c/p\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"./docs/screenshots/chat-workspace.png\" alt=\"Steward chat workspace\" /\u003e\n      \u003cp\u003e\u003cstrong\u003eConversation as the interface\u003c/strong\u003e\u003cbr /\u003eAsk why the NAS was slow yesterday and get an answer backed by live state.\u003c/p\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"./docs/screenshots/device-detail.png\" alt=\"Steward device detail and management surface\" /\u003e\n      \u003cp\u003e\u003cstrong\u003eDevice detail and management surface\u003c/strong\u003e\u003cbr /\u003ePer-device health, credentials, capabilities, autonomy tier, and recent actions.\u003c/p\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"./docs/screenshots/topology-map.png\" alt=\"Steward topology and dependency map\" /\u003e\n      \u003cp\u003e\u003cstrong\u003eTopology and dependencies\u003c/strong\u003e\u003cbr /\u003eUnderstand blast radius, upstream dependencies, and the shape of the network at a glance.\u003c/p\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## What Steward Is\n\n- A Next.js 16 + React 19 application with both operator UI and JSON APIs\n- A persistent `discover -\u003e understand -\u003e act -\u003e learn` agent loop with manual and scheduled execution\n- SQLite-backed state, audit history, settings history, graph projections, protocol sessions, widget state, dashboard layout state, and device adoption records\n- An encrypted vault for device credentials, provider secrets, OAuth tokens, and web research API keys using OS-native key protection plus AES-256-GCM\n- Device discovery across passive ARP, mDNS, SSDP, multicast discovery, active nmap sweeps, reverse DNS, packet capture hints, browser observation, and service fingerprinting\n- Device classification heuristics that infer type, vendor, OS family, management protocols, and confidence scores\n- A graph-backed topology model linking devices, services, workloads, assurances, access methods, profiles, and site/subnet membership\n- Incidents, recommendations, approvals, playbook runs, daily digests, and action logs\n- A policy engine with autonomy tiers, action classes, maintenance windows, quantitative risk scoring, TTL-based approvals, escalation, rollback hooks, and quarantine on repeated failure\n- A broker-first execution layer for SSH, HTTP, WebSocket, MQTT, WinRM, PowerShell over SSH, WMI, SMB, RDP, VNC-backed remote desktop, and local-tool operations\n- Device-scoped chat with live context, graph queries, onboarding flows, browser-backed web sessions, remote terminal access, and widget generation\n- Adapter management with file-backed and managed adapter packages, manifests, tool skills, runtime config, and adapter-contributed playbooks\n- A mission-control layer with DB-backed missions, subagents, investigations, briefings, Telegram gateway bindings, and pack inventory\n- Device widgets, widget controls, per-device automations, and dashboard widget pages\n- RBAC, local auth bootstrap, session auth, API token auth, OIDC SSO, and LDAP login\n- DB-backed runtime, system, auth-token, and auth settings with mutation history and as-of reads\n\n## Core Capabilities\n\n### Discovery and inventory\n\nSteward combines passive and active discovery so it can do more than ping a subnet. The current implementation uses ARP data, mDNS, SSDP, multicast discovery, nmap scans, reverse DNS, packet intel via `tshark`, browser-based observation of web consoles, TLS and HTTP inspection, SSH banner capture, SNMP and DNS probing, WinRM endpoint checks, MQTT broker checks, SMB negotiation, and NetBIOS hints.\n\nEach device record carries services, protocols, evidence, metadata, timestamps, adoption state, and graph relationships. Discovery is not a one-shot import; it is part of the recurring agent loop.\n\n### Operator control plane\n\nThe app already exposes real operator surfaces for:\n\n- Dashboard\n- Missions\n- Subagents\n- Packs\n- Gateway\n- Digest\n- Devices\n- Discovery\n- Topology\n- Incidents\n- Activity\n- Approvals\n- Policies\n- Chat\n- Adapters\n- Access control\n- Settings\n\nPer-device pages go beyond inventory. They include access methods, stored credentials, adapter/profile binding, workloads, assurances, findings, chat, widgets, automations, remote desktop, and remote terminal access.\n\n### Durable autonomy\n\nSteward now separates long-lived agency from one-shot chat turns.\n\n- `Workloads` and `assurances` remain the concrete device-scoped contracts and checks.\n- `Missions` sit above them and represent durable goals such as availability watch, certificate watch, backup hygiene, storage health, WAN guardian, and daily briefing.\n- `Subagents` now carry typed scope and autonomy policy: domain, allowed mission kinds, approval mode, channel voice, escalation windows, and autonomy budgets.\n- `Subagents` also persist mission-run memory, standing orders, cross-mission delegations, and mission plans so ownership survives across turns and across days.\n- `Investigations` persist follow-up across restarts and across days, with stage-based state (`detect -\u003e correlate -\u003e hypothesize -\u003e probe -\u003e decide -\u003e act -\u003e verify -\u003e explain`), evidence, recommended actions, unresolved questions, and step history.\n- `Briefings` are stored artifacts, not transient UI strings, and are compiled separately from durable channel delivery jobs.\n- `Missions` support `shadowMode` so a domain can stage ownership and briefing behavior before operator-facing delivery or action.\n- Chat sessions can now be formally bound to `missionId`, `subagentId`, and `gatewayThreadId`, so Telegram threads and in-app conversations share the same durable mission context.\n\nThis cutover is DB-backed and additive. It does not move product behavior into environment variables.\n\n### Safe automation and remediation\n\nSteward does not jump straight from detection to mutation. The repo has a real approval and execution pipeline with policy evaluation, risk scoring, approval TTLs, escalation, safety gates, execution lanes, idempotency keys, verification steps, rollback sequences, and failure quarantine.\n\nBuilt-in playbooks currently cover:\n\n- systemd, Docker, and Windows service recovery\n- TLS certificate renewal\n- rsync backup retry\n- NAS snapshot verification\n- disk cleanup\n- configuration backup over SSH or HTTP\n\n### Assistant, remotes, and generated surfaces\n\nThe conversational layer runs against live local state, not a static prompt. It can answer from devices, incidents, graph structure, recent changes, and device-scoped context, then route into first-party operations.\n\nThe current codebase also includes:\n\n- Browser-backed web sessions for recurring appliance UIs\n- In-app remote desktop sessions for RDP and VNC via `guacd`\n- A per-device remote terminal that selects SSH, WinRM, or PowerShell-over-SSH based on observed access\n- Generated device widgets with first-class controls backed by the operation runtime\n- Per-device automations that can run widget controls on manual, interval, or daily schedules\n\n### Extensibility\n\nSteward is already designed to be extended in-repo. Adapters can contribute discovery, enrichment, capability mapping, deterministic profile matching, tool skills, and playbooks. The app includes adapter package CRUD, config editing, tool-skill configuration, and built-in starter adapters for HTTP surfaces, Docker operations, and SNMP-derived network intelligence.\n\nThe new pack system broadens that model. Packs can now carry:\n\n- subagents\n- mission templates\n- workload and assurance templates\n- finding templates\n- investigation heuristics\n- playbooks\n- report templates\n- briefing templates\n- gateway templates\n- adapters and tools\n- lab fixtures\n\nManaged pack lifecycle is now a first-class API surface:\n\n- manifest validation\n- Steward compatibility checks\n- signer registry and Ed25519 signature verification for verified packs\n- materialized pack resources\n- install and upgrade history\n- enable / disable / remove flows without touching product env vars\n\n## LLM and Provider Support\n\nThe repo supports multiple model backends and local endpoints. Current provider support includes:\n\n- OpenAI\n- Anthropic\n- Google\n- Mistral\n- Groq\n- xAI\n- Cohere\n- DeepSeek\n- Perplexity\n- Fireworks\n- Together AI\n- OpenRouter\n- Ollama\n- LM Studio\n- Custom OpenAI-compatible endpoints\n\nWeb research is also configurable through DB-backed settings and can use Brave scraping, DuckDuckGo scraping, Brave API, Serper, or SerpAPI.\n\n## Quickstart\n\n### Local development\n\n```bash\nnpm install\nnpm run dev\n```\n\nOpen [http://localhost:3010](http://localhost:3010).\n\nFirst-time flow:\n\n1. Visit `/access` and bootstrap the first account.\n2. Configure at least one LLM provider.\n3. Run the agent loop from the UI or call `POST /api/agent/run`.\n4. Review discovered devices.\n5. Add credentials only where Steward should actually manage a device.\n6. Tune runtime and system settings from the UI.\n7. Configure a Telegram gateway binding if you want chat-native briefings and approvals.\n\n### Docker compose\n\n```bash\ndocker compose up --build\n```\n\nThis stack includes:\n\n- Steward on port `3010`\n- `guacd` for in-app remote desktop sessions\n- Persistent local state mounted at `./.steward`\n\n### Production scripts\n\nmacOS / Linux / WSL:\n\n```bash\nchmod +x ./scripts/install-prod.sh\nchmod +x ./scripts/run-prod.sh\n./scripts/install-prod.sh\n./scripts/run-prod.sh\n```\n\nWindows PowerShell:\n\n```powershell\n./scripts/run-prod.ps1\n```\n\n## Validation\n\nBefore merging or cutting a build, run:\n\n```bash\nnpm run lint\nnpm run test\nnpm run build\n```\n\nThe repository now includes a GitHub Actions workflow that runs the same `lint -\u003e test -\u003e build` sequence on pushes and pull requests.\n\nAutonomy-specific validation now includes:\n\n- pack signer and verified-pack API coverage\n- Telegram gateway threading and inbound dedupe coverage\n- mission replay fixtures for WAN, backup, and certificate guardians\n- schema migration coverage for chat-thread and pack-signing cutover\n- restore-drill coverage for the autonomy schema backup path\n\n## Host tooling\n\nThe repo expects real network tooling. The install scripts and postinstall hooks ensure or attempt to install:\n\n- `nmap`\n- `tshark`\n- SNMP tools\n- Playwright browser runtime\n- PowerShell\n- `guacd` or Docker-based `guacd` for remote desktop features\n\n## State and Security Model\n\nSteward stores local data under `.steward/`:\n\n- `steward_state.db`\n- `steward_audit.db`\n- `vault.enc.json`\n- `vault.key`\n\nRuntime and product settings are persisted in SQLite. Provider metadata is DB-backed, while provider secrets and device credentials are stored in the encrypted vault. API access can be gated by a DB-backed auth token, and operator access can be managed through local users, OIDC, or LDAP.\n\n## Notification MVP\n\nThe current public-beta outbound notification surface is intentionally narrow:\n\n- Telegram\n- Generic outgoing webhooks\n\nEmail, Slack, Teams, SMS, and push delivery are deliberately deferred until after the first public-beta release.\n\nTelegram is now more than a notification sink. Steward includes a Telegram-first gateway with:\n\n- DB-backed gateway bindings\n- inbound webhook processing\n- inbound update dedupe\n- durable thread-to-chat-session binding\n- mission, subagent, investigation, and status commands\n- natural-language prompts such as \"what are you watching\", \"show open missions\", and \"why was \u003cdevice\u003e slow\"\n- briefing compilation plus durable `channel.delivery` jobs\n- durable `approval.followup` reminders when approvals are aging in the queue\n- approval and deny commands for pending playbook actions\n\nThe dashboard and device contract surface are now mission-aware as well:\n\n- `/` surfaces active missions, active investigations, pending approvals, and recent briefings before lower-level widgets\n- device contract pages show mission ownership over committed workloads and assurances\n- `/api/autonomy/metrics` and the home dashboard surface queue lag, worker health, mission latency, briefing latency, and channel delivery latency\n\n## API Surface\n\nCore endpoints:\n\n- `GET /api/health`\n- `GET /api/state`\n- `POST /api/agent/run`\n- `POST /api/chat`\n\nSettings:\n\n- `GET/POST /api/settings/runtime`\n- `GET/POST /api/settings/system`\n- `GET/POST /api/settings/auth-token`\n- `GET /api/settings/history?domain=runtime|system|auth`\n\nInventory and operations:\n\n- `GET/POST /api/devices`\n- `GET /api/devices/:id/adoption`\n- `GET/POST /api/devices/:id/credentials`\n- `GET/POST /api/devices/:id/widgets`\n- `GET/POST /api/devices/:id/automations`\n- `GET/PATCH /api/incidents`\n- `GET /api/approvals`\n- `POST /api/approvals/:id`\n- `GET/POST /api/playbooks/runs`\n- `GET /api/audit-events`\n- `GET/POST /api/digest`\n\nAutonomy:\n\n- `GET /api/autonomy/metrics`\n- `GET/POST /api/missions`\n- `GET/PATCH /api/missions/:id`\n- `GET /api/missions/:id/delegations`\n- `GET /api/missions/:id/plan`\n- `POST /api/missions/:id/run`\n- `GET /api/subagents`\n- `GET/PATCH /api/subagents/:id`\n- `GET/POST /api/subagents/:id/orders`\n- `GET /api/investigations`\n- `GET/PATCH /api/investigations/:id`\n- `GET/POST /api/packs`\n- `GET/POST /api/packs/signers`\n- `GET/PATCH/DELETE /api/packs/signers/:id`\n- `GET/PATCH/DELETE /api/packs/:id`\n- `POST /api/packs/:id/toggle`\n- `GET /api/devices/:id/autonomy`\n- `GET/POST /api/gateway/bindings`\n- `GET/PATCH/DELETE /api/gateway/bindings/:id`\n- `POST /api/gateway/telegram/:bindingId/webhook`\n- `GET/POST /api/briefings`\n\nIdentity and providers:\n\n- `GET /api/auth/me`\n- `POST /api/auth/bootstrap`\n- `POST /api/auth/login`\n- `POST /api/auth/logout`\n- `GET/POST/PATCH/DELETE /api/auth/users`\n- `GET/POST /api/providers`\n- `GET /api/providers/models`\n- `GET/POST /api/vault`\n\nRemote access:\n\n- `GET/POST /api/remote-desktop/sessions`\n- `POST /api/remote-desktop/sessions/:id/viewer-bootstrap`\n- `GET/POST /api/devices/:id/remote-terminal`\n\n## Contributing\n\nIf you are contributing:\n\n- Keep runtime and product configuration DB-backed\n- Prefer deterministic execution paths and auditable state transitions\n- Update public docs when product behavior changes\n\n## License\n\nSteward is available under the [MIT License](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbraedonsaunders%2Fsteward","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbraedonsaunders%2Fsteward","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbraedonsaunders%2Fsteward/lists"}