astrid README

The project's README from github.com/astrid-runtime/astrid. As one markdown file: README.md.

Astrid

Software should compose without inheriting each other's authority.

CI CodeQL License: MIT OR Apache-2.0 MSRV Rust 2024 The Astrid Book


Astrid is an operating-system project for software built from WebAssembly capsules. Today it runs as a portable user-space runtime on macOS and Linux; the direction is a standalone operating system. This release is the hosted runtime, not a bootable OS image.

Run components in a sandbox, connect them through typed interfaces, and give each principal its own capabilities and durable state. Install, upgrade, and remove capsules while the runtime is running.

Use it to build agent systems, tools, services, or your own distribution. Astrid does not choose a product, model provider, agent loop, or user interface for you.

Agents make the problem urgent: a model can choose what to do, but that should not make the model the authority that permits it. Astrid separates those jobs. The same foundation serves software without an LLM—components can be replaced and composed without putting application policy into the kernel.

Get started · Write a capsule · Read the Book · Release notes

Quick start

Install Astrid using one of the options below, then start an uncomposed runtime—no model account or distribution required:

astrid --version
astrid start
astrid status
astrid capsule list
astrid stop

status reports the running daemon; a fresh uncomposed runtime has no product capsules. stop shuts it down and retires its working state into astrid.volume. Starting again restores the working projection.

Next, build your first capsule, or choose a distribution you trust with astrid init --distro <source>. A distribution supplies the capsule composition and configuration; Astrid does not select one implicitly. See initial setup for repository, local-manifest, and signed-bundle inputs.

Start with the Book for the architecture or the Contributor Handbook to contribute.

Why Astrid exists

Agent frameworks put trust in the prompt. Astrid puts it in the runtime. An agent is untrusted code executing on your machine with access to your files, your network, and your credentials. Telling it to behave is not a security boundary. An OS-grade boundary is.

How it works

Frontends (the CLI, the HTTP gateway, Discord, and so on) are uplinks: protocol clients that connect to the daemon over a Unix domain socket and speak in IPC events. There is no Frontend trait. An uplink publishes events and receives responses like any other bus participant.

flowchart TB
    CLI[CLI] -->|IPC events over Unix socket| Kernel
    HTTP[HTTP gateway] -->|IPC events| Kernel
    Discord[Discord] -->|IPC events| Kernel
    Uplinks[Other uplinks] -->|IPC events| Kernel

    subgraph Runtime[Astrid]
        Kernel[Kernel: astrid-daemon<br/>dumb event router<br/>event bus - capability ACL - audit chain - Wasmtime sandbox]
        Capsules[WASM Component capsules: wasm32-unknown-unknown<br/>providers - orchestrators - tools - fs - http - sessions - registry - identity]
    end

    Kernel -->|capability-checked host calls<br/>astrid:* WIT ABI| Capsules

Capsules communicate exclusively through the bus. Each declares what it needs and what it provides in a Capsule.toml manifest with typed [imports]/[exports] tables; the kernel resolves the dependency graph by topological sort and boots capsules in order. Tools are an IPC convention, not a kernel concept: a tool capsule intercepts tool.v1.execute.<name>, and the kernel never sees a tool schema.

The host ABI is the WebAssembly component model with versioned astrid:* WIT packages: fs, io, kv, ipc, net, http, sys, process, approval, identity, elicit, and uplink. Guests import only what their manifest allows, and every call is capability-gated at the boundary.

The security model

Astrid's security is decomposed. There is no single gate every action funnels through. A capsule has no ambient authority, and authorization is enforced by independent, per-area mechanisms, each fail-closed and each enforced where the effect actually happens.

flowchart TB
    Action[A capsule action] --> Sandbox[WASM sandbox<br/>no syscalls, file descriptors, or host memory<br/>external resources are capability-checked host calls]
    Action --> Manifest[Manifest gate<br/>declared file, network, and process allow-list<br/>empty is deny-all; path traversal and SSRF defenses]
    Action --> IPC[IPC ACL<br/>declared publish and subscribe topics only<br/>per-principal routing]
    Action --> Capability[Capability token<br/>ed25519, principal-bound, scoped, expiring, revocable<br/>per-device tokens can be subset-scoped]
    Action --> Approval[Approval gate<br/>once - session - always - deny<br/>allow always mints a token; local egress elicits consent]
    Action --> OS[OS sandbox<br/>bwrap on Linux - seatbelt on macOS for native subprocesses]
    Action --> Audit[Audit chain<br/>signed, hash-linked JSONL decisions and calls<br/>split per principal and independently verifiable]

These mechanisms are real and independently tested. There is no unified interceptor orchestrating them. The five-layer gate chapter of The Astrid Book walks each layer against the source.

Install

Release archives:

Download the archive for your machine from GitHub Releases. Keep its companion binaries and platform files together when extracting it; add the extracted directory to your PATH.

The 2026.9.0 release targets are:

Platform Architectures Filesystem frontend
macOS Apple Silicon, Intel FSKit on macOS 26+; signed app and extension approval required
Linux GNU x86_64, ARM64 FUSE
Linux MUSL x86_64, ARM64 FUSE

Windows is tested in CI but is not included in this release's archives. For migration and platform limitations, read the 2026.9.0 upgrade notes. Versions now follow year.month.patch.

Homebrew (macOS and Linux):

brew tap astrid-runtime/tap
brew install astrid

From crates.io (requires Rust 1.95+):

cargo install astrid

From source:

git clone https://github.com/astrid-runtime/astrid
cd astrid && cargo build --release   # binary at ./target/release/astrid

The core tools are listed below. Platform release archives additionally include their filesystem provider and, on macOS, the signed AstridFS app and management scripts. A Cargo install is not a substitute for that signed macOS bundle.

Binary Role
astrid CLI uplink. Connects to the daemon over the Unix socket. TUI, headless mode, capsule and agent management.
astrid-daemon The kernel process. Loads capsules, routes IPC, enforces capabilities, runs the sandbox.
astrid-build Capsule compiler and packager. Builds to wasm32-unknown-unknown.
astrid-emit Stdio-to-bus bridge for external hook producers.

Initial setup

astrid init --distro <source> fetches a distro (a curated capsule bundle), presents any selection groups declared by that distro, and prompts for its required configuration. Secrets are stored per principal in the secret store, never passed on the command line. init writes a Distro.lock pinning every capsule by BLAKE3 hash, so the same explicit distro input reproduces the same fleet.

astrid init --distro @yourorg/your-distro          # repository distro
astrid init --distro ./Distro.toml                  # local manifest
astrid init --distro ./bundle.shuttle --offline     # signed bundle, no network
astrid init --distro @yourorg/your-distro --yes     # non-interactive defaults

When a distro includes an LLM provider, onboarding can discover that provider's live model list from its /v1/models endpoint. If the distro also includes an agent loop, confirm that it is ready before starting a session:

astrid doctor    # daemon up? capsules ready? an LLM available?
astrid chat      # interactive session; the daemon auto-starts on first use
astrid models    # list the current provider's models (a registry-capsule verb)

Headless and scripting

astrid -p "summarize the git log"                    # single prompt, prints and exits
git diff HEAD~1 | astrid -p "write a commit message" # stdin is appended to the prompt
astrid -p "fix all failing tests" --yes              # auto-approve tool requests
astrid -p "continue" --session "$SID"                # resume by id or name

Daemon lifecycle

astrid start     # persistent daemon (survives terminal close)
astrid status    # PID, uptime, connected clients, loaded capsules
astrid ps        # loaded capsules and their lifecycle state
astrid stop      # graceful shutdown
astrid update    # authenticate, verify, and install the latest release

An explicit astrid start is persistent. Automatically started MCP gateways and ephemeral daemons instead follow client-connection lifetime: quiet connected clients keep them alive, and they retire after the final client disconnects.

Mount durable state

Once the platform filesystem frontend is installed and enabled, a principal can mount its view through the CLI:

astrid start
mkdir -p /tmp/astrid-view
astrid --principal default storage mount --as default /tmp/astrid-view
astrid --principal default storage status /tmp/astrid-view
astrid --principal default storage sync /tmp/astrid-view
astrid --principal default storage unmount /tmp/astrid-view
astrid stop

Use an empty mountpoint. Principal views and the administrative runtime view have different authority; mounting does not grant access to other principals. The files live in Astrid's storage, backed by the host filesystem—not in a new disk partition. Release binaries remain outside the runtime's mutable volume.

macOS archives include macos/manage-macos-fskit.sh for app installation and enablement; follow its macOS permission guidance. Linux uses its FUSE frontend and host FUSE setup, without Apple's signing or extension-approval steps.

Per-principal isolation

Each principal (agent identity) is a fully isolated tenant: its own capsule access, KV namespace, secrets, home directory, quotas, and audit chain. New principals inherit nothing by default.

astrid agent create ci-bot                     # clean-slate, least-privilege agent
astrid agent create staging --clone production # full profile + state replica
astrid agent modify ci-bot \
  --add-capsule astrid-capsule-fs              # grant access to a capsule's tools
astrid caps show ci-bot                        # inspect capability grants
astrid quota set -a ci-bot --memory 128MB      # per-principal resource limits
astrid pair-device issue --scope use-only      # scope a device token to a subset

Capsule access is enforced kernel-side at dispatch. A principal can only invoke capsules explicitly granted to it, and two principals installing the same capsule bytes share one content-addressed on-disk artifact while getting separate in-memory runtime instances.

Write a capsule

A capsule is a WASM process described by a manifest. The scaffold generates a first-try-compiling project targeting wasm32-unknown-unknown, plus an AUTHORING.md guide.

astrid capsule new my-capsule    # scaffold Capsule.toml, Cargo.toml, src/lib.rs, .cargo/config.toml
cd my-capsule
astrid capsule build             # compile and package
astrid capsule install .         # hot-loaded into the running daemon, no restart

Capsule authors depend on astrid-sdk, which mirrors the std module layout (fs, net, process, env, time, log) and adds Astrid modules (ipc, kv, http, hooks, uplink, identity, approval). The #[capsule] proc macro generates the WASM ABI boilerplate: exports, serialization, and dispatch for tools, commands, hooks, and lifecycle entry points.

use astrid_sdk::prelude::*;

#[derive(Default)]
struct Weather;

#[capsule]
impl Weather {
    #[astrid::tool]
    fn forecast(&self, args: ForecastArgs) -> Result<Forecast, SysError> {
        let key = env::var("WEATHER_API_KEY")?;
        let body = http::get(&format!("https://api.example.com/wx?q={}", args.city))?;
        Ok(serde_json::from_slice(&body)?)
    }
}

Building capsules is a first-class workflow in Astrid. The Forge (astrid capsule new plus authoring tools and runtime-served guidance) is the on-ramp; the direction is an agent that writes, builds, and installs its own capsules within the capability sandbox.

Reproducible builds and deterministic tests are consumers of Muninn's verified computation memory: complete source and toolchain closures become derivation inputs, so an unchanged fleet build is a verified lookup while install, signing, and publication remain fresh authorized effects.

Live capsule lifecycle

astrid capsule install @org/capsule-name   # install and hot-load
astrid capsule update my-capsule           # hot-swap the running instance
astrid capsule remove my-capsule           # live-unload, no restart
astrid capsule list --verbose              # installed capsules with capability metadata
astrid capsule tree                        # imports/exports dependency graph

What's new in 2026.9.0

See the full changelog, upgrade notes, and dependency inventory for the release details.

Documentation

Development

cargo build --workspace
cargo test --workspace -- --quiet
cargo clippy --workspace --all-features -- -D warnings
cargo fmt --all -- --check

All crates enforce #![deny(unsafe_code)] except astrid-sys and astrid-sdk, where WASM FFI requires it. Clippy runs at pedantic level and integer-overflow arithmetic is a lint error. Release binaries for macOS and GNU/musl Linux (x86_64 and aarch64) are built on tag push and signed with keyless Sigstore. Self-managed updates authenticate the exact archive and its pinned Astrid release-workflow identity before independently checking the BLAKE3 manifest and extracting any bytes. Homebrew and Cargo remain responsible for updates they install; signed SHA-256 manifests remain available for their compatibility requirements. GitHub build-provenance attestations are published as additional evidence and are not substituted for the updater's release-archive signature. See the self-update security model.

Contributing

Contributions are welcome. Astrid uses a tiered contributor system that protects security-critical code while keeping the door open to new contributors. Every pull request must be linked to a GitHub issue. See CONTRIBUTING.md for the issue-first workflow and tier descriptions.

Changes to any contract surface (the host ABI, the IPC protocol, the capability model, the manifest schema, or the SDK public API) go through the RFC process in the RFCs repository before implementation.

License

Dual-licensed under MIT and Apache 2.0, at your option.

Copyright (c) 2025-2026 Joshua J. Bouw and Unicity Labs.

astrid (astrid-runtime/astrid)

Searching Database…

10.3K ·GitHub
这是什么?Astrid 是一个可移植、具备能力安全机制、面向可组合软件的操作系统:应用是沙箱化的 WebAssembly 胶囊,通过类型化接口相互连接,每个胶囊拥有自己的能力和持久化状态。
它是要我开机引导进去的操作系统,还是装在我现有系统上的程序?目前它是运行在 macOS 和 Linux 上的托管用户态运行时(一个守护进程加一个命令行工具),不是可引导镜像——独立操作系统是官方声明的后续方向。
我怎么把它跑起来?可以通过 GitHub Releases、Homebrew、crates.io(需要 Rust 1.95+)或从源码安装,然后运行 astrid status——运行时以未组合状态启动,不需要任何模型账号。之后可以用 astrid init --distro 添加一份胶囊包。
我需要先有 OpenAI 或 Anthropic 账号它才能干活吗?不需要——未组合的运行时既不需要模型账号也不需要 distro。Astrid 从不替你选择模型提供商或 agent 循环;LLM 组件来自你明确选择的 distro,密钥保存在按主体隔离的密钥库中,绝不会出现在命令行上。
它能在 Windows 上运行吗?这个版本不行:Windows 在 CI 中有测试,但未包含在 2026.9.0 的压缩包里。目前支持的平台是 macOS(Apple Silicon 和 Intel)以及 Linux x86_64/ARM64,均有 GNU 和 MUSL 两种构建。
为什么 agent 需要操作系统——写好提示词不就能保证安全了吗?README 说得很直白:要求模型守规矩并不是安全边界。每一个文件路径、网络主机和工具都是经 ed25519 签名的 capability 授权;胶囊在 Wasmtime 中运行,没有系统调用、文件描述符或宿主内存,而且刻意做得极简的内核不保存任何 LLM 状态,因此胶囊的 bug 无法破坏共享的内核状态。
什么是胶囊(capsule)?我自己能写一个吗?胶囊是一个在 Capsule.toml 清单中声明的 WASM 进程,带有类型化的 [imports]/[exports];胶囊之间只通过事件总线、基于 WIT 类型化 ABI 通信。astrid capsule new 可以生成一个能编译的 Rust 项目脚手架(基于 astrid-sdk,带 #[capsule] 宏),再用 astrid-build 打包成 wasm32-unknown-unknown。
系统能在运行中安装或升级组件吗?可以——胶囊的在线生命周期管理是主打功能:在运行中的守护进程上安装、升级和移除胶囊,无需重启。astrid init --distro 会写出一个 Distro.lock,用 BLAKE3 哈希锁定每一个胶囊,因此同样的显式输入能复现同样的胶囊集群。
我在自己的电脑桌面上怎么查看 agent 的文件?通过命令行工具挂载该主体的视图:macOS 使用 FSKit(需要 macOS 26+,并需批准签名的应用和扩展),Linux 使用 FUSE。要挂载到空的挂载点上——你只能看到该主体的数据,这些文件保存在 Astrid 由宿主文件系统支撑的内容寻址存储里,而不是一个新分区。
What are similar projects?lean-ctx, pdfcraft, aos-ce, figcraft, lightcraft, box, oar, wasmtime
Size
22 MB
Stars
10.3K
Age
8mo
Commits · 90 Days