{"id":50413573,"url":"https://github.com/noisyloop/everythingos","last_synced_at":"2026-05-31T05:01:04.098Z","repository":{"id":333788689,"uuid":"1138736408","full_name":"noisyloop/EverythingOS","owner":"noisyloop","description":"A security-first, powerful, extensible multi-agent framework for building autonomous systems.","archived":false,"fork":false,"pushed_at":"2026-05-17T20:57:59.000Z","size":18985,"stargazers_count":2,"open_issues_count":11,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-17T22:47:52.187Z","etag":null,"topics":["ai","ai-agents","automation","automation-framework","autonomous-agents","autonomous-robots","cybersecurity","robotics-control","typescript"],"latest_commit_sha":null,"homepage":"","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/noisyloop.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":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-21T03:47:02.000Z","updated_at":"2026-05-17T20:39:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/noisyloop/EverythingOS","commit_stats":null,"previous_names":["m0rs3c0d3/everythingos","noisyloop/everythingos"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/noisyloop/EverythingOS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noisyloop%2FEverythingOS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noisyloop%2FEverythingOS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noisyloop%2FEverythingOS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noisyloop%2FEverythingOS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noisyloop","download_url":"https://codeload.github.com/noisyloop/EverythingOS/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noisyloop%2FEverythingOS/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33719601,"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-05-31T02:00:06.040Z","response_time":95,"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":["ai","ai-agents","automation","automation-framework","autonomous-agents","autonomous-robots","cybersecurity","robotics-control","typescript"],"created_at":"2026-05-31T05:01:03.294Z","updated_at":"2026-05-31T05:01:04.091Z","avatar_url":"https://github.com/noisyloop.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EverythingOS\n\n\u003e **A security-first multi-agent framework for building autonomous systems.**  \n\u003e NIST AI RMF aligned · Production-grade architecture · Community contributions welcome\n\nThis README is written for three different readers. Go to yours — the sections are deliberately separate and do not repeat each other:\n\n- [**1 · Build a custom agent**](#1--build-a-custom-agent) — you want to ship an agent today.\n- [**2 · Security evaluation**](#2--security-evaluation) — you're assessing this for a deployment.\n- [**3 · The decision**](#3--the-decision) — you're deciding whether to adopt it.\n\n---\n\n# 1 · Build a custom agent\n\n*For the developer who wants working code, not a security lecture.*\n\n## What this actually does\n\nYou write small classes called **agents**. An agent reacts to events (\"a message arrived\", \"a timer ticked\"), does some work, and emits events of its own. EverythingOS is the layer underneath that handles the annoying-but-critical parts for you: authenticating every message an agent sends, cleaning untrusted input before it reaches a model, recording an audit trail, and rate-limiting runaway loops. You write the behavior; the framework keeps it accountable.\n\n## Run it in ~15 minutes\n\n```bash\ngit clone https://github.com/noisyloop/EverythingOS\ncd EverythingOS\nnpm ci          # use ci, not install — lockfile is law\n\n# Create .env with a signing secret (required in production):\necho \"EOS_AGENT_SECRET=$(node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\")\" \u003e .env\n\nnpm test           # run the full test suite\nnpm run e2e:proof  # prove the whole stack works, end to end, with no mocks\n```\n\n`npm run e2e:proof` is the fastest way to see the system actually work: it registers a real agent, pushes untrusted input through the sanitization pipeline, writes a file, emits over the event bus, and verifies a tamper-evident ledger entry. If any layer is broken it names the layer and exits non-zero.\n\n## Make your own agent\n\n```bash\nnpx everythingos new my-agent     # alias: npx eos new my-agent\n```\n\nIt asks two questions — a **risk tier** (LOW / MEDIUM / HIGH) and a **description** — then generates `src/agents/my-agent/index.ts` from the maintained template at `src/agents/_scaffold`. A generated agent looks like this (real, trimmed):\n\n```ts\nexport const MANIFEST: AgentManifest = validateManifest({\n  id: 'my-agent',\n  name: 'My Agent',\n  version: '0.1.0',\n  category: 'foundation',\n  description: 'What this agent does — at least 10 characters.',\n  capabilities: ['eventbus:publish', 'eventbus:subscribe'],\n  trustLevel: AgentRiskTier.LOW,\n  tags: ['my-agent'],\n  author: 'You',\n});\n\nexport default class MyAgentAgent extends Agent {\n  constructor(config?: Partial\u003cAgentConfig\u003e) {\n    super({\n      id: MANIFEST.id,\n      name: MANIFEST.name,\n      type: 'foundation',\n      riskConfig: {\n        tier: AgentRiskTier.LOW,\n        riskJustification: 'Why this agent is safe at this tier',\n        allowedPublishChannels: ['my-agent:heartbeat'],   // exactly what you emit\n        allowedSubscribeChannels: ['my-agent:ping'],       // exactly what you hear\n      },\n      ...config,\n    });\n  }\n\n  protected async onStart(): Promise\u003cvoid\u003e {\n    this.subscribe\u003c{ from?: string }\u003e('my-agent:ping', (event) =\u003e {\n      this.log('info', 'ping', { from: event.payload.from });\n      this.emit('my-agent:heartbeat', { pong: true, agentId: this.id });\n    });\n  }\n\n  protected async onStop(): Promise\u003cvoid\u003e {}\n}\n```\n\nRegister and run it (same pattern as [`examples/demo-simple.ts`](examples/demo-simple.ts)):\n\n```ts\nimport MyAgentAgent from './src/agents/my-agent';\nimport { agentRegistry } from './src';\n\nagentRegistry.register(new MyAgentAgent());\nawait agentRegistry.start('my-agent');\n```\n\n## The rules — and why they exist\n\nThese aren't bureaucracy. Each one stops a specific failure:\n\n- **You must declare every channel you publish or subscribe to.** No wildcards. *Why:* a buggy or compromised agent physically cannot talk on channels it never declared — the blast radius is bounded by the manifest, not by hope.\n- **Every agent declares a risk tier.** *Why:* the framework applies tier-appropriate controls automatically (LLM rate limits, input/output auditing). HIGH-tier agents will not start without a registered `ApprovalGateAgent`.\n- **Untrusted input goes through `this.thinkWithUserInput()` (or `sanitizeInput()`), never raw into a prompt.** *Why:* a Unicode-aware injection/PII pipeline runs first, so a crafted message can't smuggle instructions into your model call.\n- **Consequential actions use `this.act()`, not `this.emit()`.** *Why:* `act()` emits *and* writes a tamper-evident decision-ledger entry, so the action is provable after the fact.\n\nThe manifest is Zod-validated at load time — typos fail loudly at startup, not silently in production.\n\n## What happens after your first agent runs\n\nYou now extend it: put real logic in `onStart`/`onTick`, add channels to the allowlists as you use them, call `this.think()` for LLM work (configure `llm` in the constructor), and `this.act()` for anything with real-world effect. The STEP 3 comment block in your generated file documents `setState/getState`, `healthCheck()` overrides, and the LLM helpers. When you're ready to trust the whole chain, read [`examples/e2e-proof.ts`](examples/e2e-proof.ts) — it's the worked example of an agent going through every layer for real. To extend EverythingOS to external systems or hardware without touching the core, build a **bridge** — see [`BRIDGES.md`](BRIDGES.md).\n\n---\n\n# 2 · Security evaluation\n\n*For the security engineer deciding whether this is safe to deploy. Read [`docs/STRIDE.md`](docs/STRIDE.md) alongside this — it is the authoritative threat model and it self-audits.*\n\n## What \"security-first\" means here — in code vs. as a slogan\n\n**In the codebase, concretely:** per-call HMAC signing with nonce + replay window on every `emit()`/`subscribe()`; a channel ACL that is enforced, not advisory; a mandatory input-sanitization pipeline baked into the `Agent` base class (you cannot easily bypass it); a hash-chained, tamper-evident audit log and decision ledger; CI gates that fail the build on dependency CVEs, secrets, SSRF regressions, and STRIDE claim/evidence drift; and a threat model that downgraded its own previously-false \"resolved\" markers during a verification audit.\n\n**As a slogan, honestly:** \"production-grade architecture\" describes the *design*. It is **not** a claim that isolation is finished. The largest open item — **STRIDE E-2 (CRITICAL, ❌ not implemented)** — means all agents, every tier, share one Node.js process and one V8 heap. Risk tiers are an **enforced policy control, not a memory/process isolation boundary.** `IsolatedAgentRunner` exists in the tree but has zero callers; it is not wired into the agent lifecycle. Plan for this.\n\n## Trust boundary model\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│  Single Node.js process — ONE V8 heap (NO per-agent isolation today)    │\n│                                                                         │\n│  ┌──────────────────────────────────────────────────────────────────┐  │\n│  │  Agent Orchestrator — AgentRegistry                              │  │\n│  │  (lifecycle, risk-tier preflight, emergency stop)               │  │\n│  └──────────────────────────────────────────────────────────────────┘  │\n│        │                │                 │                            │\n│   ┌────▼────┐      ┌────▼────┐       ┌────▼────┐                        │\n│   │  Agent  │      │  Agent  │       │  Agent  │   LOW · MEDIUM · HIGH  │\n│   │  (LOW)  │      │  (MED)  │       │  (HIGH) │   all share this heap  │\n│   └────┬────┘      └────┬────┘       └────┬────┘                        │\n│        └────────────────┼─────────────────┘                            │\n│                         ▼                                              │\n│  ┌──────────────────────────────────────────────────────────────────┐  │\n│  │  EventBus  (per-call HMAC sig · nonce · ACL · rate-limited)      │  │\n│  └─────────────────────────────┬────────────────────────────────────┘  │\n│                                ▼                                       │\n│  ┌──────────────────────────────────────────────────────────────────┐  │\n│  │  Security Pipeline                                              │  │\n│  │  agent-auth · sanitize (NFKC + injection) · content-filter      │  │\n│  └─────────────────────────────┬────────────────────────────────────┘  │\n│                                ▼                                       │\n│  ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────────────┐    │\n│  │ PolicyEng. │ │ ModelGuard │ │ Credential │ │ ApprovalGateAgent│    │\n│  │ /Supervisor│ │ allowlist+ │ │ Vault      │ │ (HIGH-tier human │    │\n│  │ (locked at │ │ fingerprint│ │ scoped TTL │ │  in-the-loop;    │    │\n│  │  startup)  │ │            │ │            │ │  out-of-band)    │    │\n│  └─────┬──────┘ └─────┬──────┘ └────────────┘ └──────────────────┘    │\n│        └──────────────┼───────────────────────────────────────┐       │\n│                       ▼                                        │       │\n│  ┌──────────────────────────────────────────────────────────┐ │       │\n│  │  Audit Trail + Decision Ledger                           │ │       │\n│  │  (hash-chained · async · append-only JSONL)              │ │       │\n│  └──────────────────────────────────────────────────────────┘ │       │\n│                                                                │       │\n│  ┌──────────────────────────────────────────────────────────┐ │       │\n│  │  Plugin Sandbox — SEPARATE worker_thread heap            │◄┘       │\n│  │  (the only real in-process isolation boundary today)     │         │\n│  └──────────────────────────────────────────────────────────┘         │\n└───────────────────────────────┬────────────────────────────────────────┘\n                                │  outbound only via http-guard (SSRF/DNS)\n                                ▼\n     External APIs   ·   Glasswally output dir  ──►  GlasswallyAgent\n                         (HMAC-signed IOC bundles → SOC alert events)\n```\n\nTrust boundaries **TB-1 … TB-9** (Agent↔EventBus, EventBus↔Pipeline, Agent↔LLM/ModelGuard, Agent↔CredentialVault, Main↔PluginWorker, EverythingOS↔HumanApprover, Process↔Filesystem, EverythingOS↔ExternalHTTP, EverythingOS↔Glasswally) are enumerated with per-finding analysis in [`docs/STRIDE.md`](docs/STRIDE.md). The **only** real in-process isolation boundary today is TB-5 (the plugin worker). Everything else inside the process is a control, not a wall.\n\n## What the CI gates enforce\n\nA PR cannot merge unless these pass (`.github/workflows/security.yml`): TypeScript type check; full security test suite; SSRF regression (http-guard enforcement); audit-chain integrity verification; the **STRIDE claim/evidence gate** (every ✅ in the threat model must be test-backed or audit-attested — the doc and code cannot silently diverge); `npm audit` at high/critical; Gitleaks secret scan; Node version gate; CodeQL/static analysis. SBOM generation runs on main. This is the mechanism that keeps \"security-first\" from rotting into a slogan.\n\n## Implemented controls (where the code lives)\n\nEach is a real, wired control. File paths are load-bearing.\n\n- **Per-call HMAC authentication** — fresh nonce per `emit()`/`subscribe()`, signs `agentId:channel:nonce:timestamp` with a per-agent key; 60s clock-skew window; 5-min nonce replay rejection; revocations persist to disk and survive restart. `src/security/agent-auth.ts`, `src/runtime/Agent.ts`\n- **Unicode-aware input sanitization** — NFKC normalization, zero-width stripping, whitespace collapse, then injection-pattern matching and PII scrubbing; only normalized text is forwarded, raw is hashed for audit. `src/security/sanitize.ts`\n- **HTTP guard** — SSRF blocklist (RFC1918/link-local/loopback/cloud-metadata), async DNS-rebinding revalidation, `maxRedirects: 0`, scheme blocking (CVE-2025-58754), `allowAbsoluteUrls:false` (CVE-2025-27152). A CI step rejects raw `axios` imports elsewhere. `src/security/http-guard.ts`\n- **Tamper-evident audit log** — append-only JSONL, each entry carries the prior entry's SHA-256; `verifyChain()` detects tampering in O(n); async `WriteStream`; raw content never logged. `src/security/audit-log.ts`\n- **Model Guard** — provider:model allowlist (unapproved throws before any API call) plus deterministic behavioral fingerprinting against a baseline. **Caveat (STRIDE T-2, HIGH/partial):** the fingerprint baseline is HMAC-signed with `MODEL_GUARD_SIGN_KEY` if set, otherwise it falls back to `EOS_AGENT_SECRET` and then to a hardcoded dev key — so the baseline is only as strong as that key and is forgeable by anyone who can read it unless `MODEL_GUARD_SIGN_KEY` is explicitly configured. `src/security/model-guard.ts`\n- **Credential vault** — agents get a scoped `credentialId` (provider+task, TTL ≤1h), never the raw key; every grant/expiry/revoke is logged. `src/security/credential-vault.ts`\n- **Memory safety** — `recall()` results pass back through the injection pipeline and are wrapped in an explicit \"treat as data, not instructions\" trust label. `src/services/memory/MemoryService.ts`\n- **EventBus rate limiting** — per-source 200 events/60s plus a global ceiling; stale counters purged on a timer. `src/core/event-bus/EventBus.ts`\n- **Plugin sandbox** — untrusted plugins run in a `worker_threads` heap with a memory cap, per-call timeout, structured `postMessage` only, and sanitized config in / sanitized returns out. This is the one real isolation boundary. `src/security/plugin-sandbox.ts`\n- **Glasswally integration** — tails Glasswally's eBPF enforcement output, sanitizes every free-text field through the injection pipeline, HMAC-verifies IOC bundles before forwarding (a bad signature is treated as an attack, not a data error), and maps actions to SOC severities. `src/agents/security/glasswally/index.ts`\n- **Risk-tier preflight** — declared at registration; `AgentRegistry` runs a compliance preflight on the real start path. **Honest scope (Flag/STRIDE E-2):** HIGH-tier agents must clear an `ApprovalGateAgent` preflight and approvals arrive on an authenticated out-of-band channel (not the EventBus). But because there is no per-agent process isolation, this is an **enforced runtime policy, not a containment guarantee** — a compromised in-process agent of any tier shares the heap and is not walled off by the tier system. \"No actuator without an approval gate\" holds against *honest* agents and accidental misuse; it does **not** hold against a compromised in-process agent until E-2 is implemented. `src/types/agent-risk.ts`, `src/core/registry/AgentRegistry.ts`\n\n## What is still open (do not deploy blind to these)\n\nFrom the authoritative Finding Summary in [`docs/STRIDE.md`](docs/STRIDE.md):\n\n- **E-2 — CRITICAL, ❌ NOT IMPLEMENTED.** No per-agent process isolation; risk tiers are not a security boundary. The single largest gap.\n- **S-1 (HIGH, ⚠️)** in-process token-registry exposure; **S-3 (MED, ⚠️)** runtime model-approval has no caller auth; **T-2 (HIGH, ⚠️)** fingerprint key not cryptographically separate unless `MODEL_GUARD_SIGN_KEY` is set; **I-5 (LOW, ⚠️)** approved-model list leaks via `violations.jsonl`.\n- **D-5, E-1 — research-grade (🔬):** formal proofs of the replay/approval protocols, not code tasks.\n\nAdditional honest limitations (mitigated, not eliminated): swarm mesh has no X.509 mTLS (HMAC `meshSecret` only); the credential vault seals secrets out of `process.env` only when prod-gated; built-in fingerprint probes are the default unless overridden; long-term memory uses trust-scored keyword search, not semantic provenance; Glasswally's eBPF mode requires a **separate privileged process** (`CAP_BPF`, Linux ≥5.8) — `tail` mode runs anywhere but loses kernel visibility.\n\n## NIST mapping\n\nEvery control is mapped to NIST AI RMF 1.0 / AI 600-1 / CSF 2.0 function and practice ID, with verification evidence, in [`docs/CONTROLS.md`](docs/CONTROLS.md) (GOVERN/MAP/MEASURE/MANAGE, 26 controls). Treat it as the audit/procurement artifact; treat `docs/STRIDE.md` as the adversarial one.\n\n---\n\n# 3 · The decision\n\n*Three paragraphs. No diagrams, no code.*\n\nAutonomous agents increasingly take consequential actions — moving money, deploying code, driving hardware. The unsolved operational problem is not capability; it is accountability and blast radius: when a model hallucinates a tool call or an agent is compromised, most teams cannot answer *who approved this, what exactly ran, and what was the containment*. EverythingOS exists to make those questions answerable structurally rather than by post-hoc log spelunking.\n\nExisting agent frameworks are orchestration libraries: they chain model calls and leave authentication, input sanitization, audit, and containment to whoever integrates them — which in practice means inconsistently or not at all. EverythingOS makes per-call authentication, a mandatory input-sanitization pipeline, a tamper-evident decision ledger, risk-tier preflight enforcement, and a *published, self-auditing* STRIDE threat model first-class and CI-enforced. The honest trade to weigh: today's containment is real at the plugin boundary (separate worker heap) and is *policy-enforced* at the agent boundary — full per-agent process isolation (STRIDE E-2) is on the roadmap, not shipped. If your threat model includes a compromised in-process agent, that gap is the deciding factor; if it centers on accountability, hallucinated actions, untrusted input, and supply-chain/CVE hygiene, the shipped controls are substantive and verifiable.\n\nDeployment requirements are modest: a single Node.js process (Node ≥20.20, pinned to 22.22 via `.nvmrc`), `EOS_AGENT_SECRET` set in production, optional `MODEL_GUARD_SIGN_KEY` and prod-gated secret sealing, and no external database — the audit log and decision ledger are append-only JSONL on the local filesystem (size and rotation are your responsibility). Glasswally is optional and, for kernel-level detection, needs a separate privileged eBPF process. Licensed MIT. The fastest due-diligence step is `npm run e2e:proof` plus a read of `docs/STRIDE.md`: the first proves the pipeline runs end-to-end with no mocks; the second tells you, in the project's own words, exactly what is and isn't done.\n\n---\n\n## Contributing\n\nEverythingOS is built on the premise that agentic security is a hard, unsolved problem. The open items above are not a bug list — they're research and engineering problems the community is better positioned to solve together.\n\n- **Open a Discussion** if you've worked on agent security, formal verification, secrets management, or distributed systems.\n- **Security findings:** follow [`SECURITY.md`](SECURITY.md). Don't open public issues for unpatched vulnerabilities.\n- **New controls:** PRs welcome — include the threat being mitigated and a test demonstrating the attack path.\n- **NIST/compliance:** if declared alignment and implementation diverge, open an issue.\n- **Hardware/robotics safety:** the swarm and hardware layers have the weakest safety properties; functional-safety and ROS 2 security expertise is especially welcome.\n\nBefore opening a PR: `npm test`, `npm run typecheck`, `npm run audit:check`, and add a test for the security property you changed.\n\n## License\n\nMIT\n\n---\n\n*EverythingOS is part of the [noisyloop](https://github.com/noisyloop) security tooling portfolio. Built under the Robots For Peace framework — autonomous systems should be auditable, constrained, and accountable.*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoisyloop%2Feverythingos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoisyloop%2Feverythingos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoisyloop%2Feverythingos/lists"}