Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@ openblox runs untrusted, machine-generated code in disposable Linux sandboxes.
It is a **Go library first** and a daemon second. There is no control plane, no
database, and no scheduler. A sandbox is a container; the container is the state.

## Non-goals
openblox is deliberately the layer *below* a sandbox platform. If you need
scheduling, tenancy or an API of your own, build them on top — the absence of a
control plane here is what makes that possible, rather than something you have
to work around.

## The rule

One line decides whether something belongs in openblox:

> **How a sandbox is isolated is openblox's problem.
> Which sandbox runs where is yours.**

Stating these up front, because every one of them is a place a sandbox project
grows into a platform:
Isolation is the runtime, the egress policy, the filesystem, the user, the
capabilities, the resource caps and the lifetime bounds. Placement is
scheduling, queueing, tenancy, metering, fleet membership and snapshots.

Every non-goal below is an application of that rule, not a separate opinion —
which is why the list has not grown and is not expected to.

## Non-goals

- **No multi-tenant SaaS.** No organizations, billing, usage metering, or audit log.
- **No scheduler.** One host, one daemon. Not a fleet.
Expand All @@ -17,8 +33,10 @@ grows into a platform:
- **No sub-second cold starts.** Correctness and containment over latency.
- **No database.** Container labels are the registry.

If you need those, you want a hosted platform. That is a legitimate need and
openblox is the wrong tool for it.
If you need those, build them on top of openblox or use a hosted platform. Both
are legitimate; neither belongs in here. A feature request that crosses the rule
is declined by pointing at the rule, which is the only way a project this small
stays this small.

## Shape

Expand Down
17 changes: 17 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Contributing

## Scope

Read this before proposing a feature. One rule decides what belongs in openblox:

> **How a sandbox is isolated is openblox's problem.
> Which sandbox runs where is yours.**

Isolation is in scope: runtimes, egress policy, filesystem, users, capabilities,
resource caps, lifetime bounds. Placement is not: scheduling, multi-node, tenancy,
metering, snapshot/resume, an API server, a database.

openblox is the layer below a sandbox platform. Anything on the placement side is
something you can build on top, and keeping it out is what keeps this small enough
to audit. A PR that crosses the rule will be declined on that basis, however good
it is — so please open an issue before writing one. [ARCHITECTURE.md](ARCHITECTURE.md)
has the reasoning.

## Setup

```bash
Expand Down
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,30 @@ openblox takes the third option: a substrate small enough to read in an
afternoon, that you run yourself, with isolation supplied by gVisor rather than
by hope.

## Where this sits

openblox is the layer *below* a sandbox platform, not a smaller one.

```
your scheduler, your tenancy, your API ← yours to build, if you ever need it
──────────────────────────────────────
openblox ← isolation, done correctly
──────────────────────────────────────
Docker + gVisor ← the boundary itself
```

One rule decides what belongs here:

> **How a sandbox is isolated is openblox's problem.
> Which sandbox runs where is yours.**

Egress, capabilities, filesystem, resource caps, lifetime, runtime: openblox's.
Placement, queueing, tenancy, metering, snapshots: not openblox's, and not
planned. Build those on top when something actually asks for them. That is what
a lower layer is for, and it is why there is no control plane to adopt first.

The comparison is `libvirt`, not OpenStack.

## Secure by default

The zero value of every option is the safe one. A sandbox created with no
Expand All @@ -81,6 +105,16 @@ If the host cannot provide the requested isolation, `Create` fails with
sandbox that is quietly less isolated than you asked for is worse than no
sandbox, because you keep trusting it.

**Two levels of the same guarantee.** In the library, *your* code chooses: the
defaults are safe, and every relaxation is explicit and greppable at the call
site. Through [`openbloxd`](https://openblox.sh/security/#deploying-the-policy-broker-openbloxd)
the choice stops being the caller's at all — profiles live in the daemon's
config file and no request can reach them. A caller names a profile. It cannot
name an image, a runtime, a user, an egress policy, or a resource cap.

That is the difference between weakening being **visible** and weakening being
**unreachable**, and it is the whole reason the daemon exists.

## What you get

| | |
Expand All @@ -93,13 +127,18 @@ sandbox, because you keep trusting it.

## What it is not

The first three follow from the rule above — they are placement, not isolation.
The fourth is a trade made on purpose.

- **Not multi-tenant.** No organizations, auth, billing, or metering. Tenancy is
the caller's concern.
- **Not a fleet.** One host, one daemon.
- **No snapshot, fork, or pause/resume.** Stop and re-create from a baked image.
- **Not the fastest.** Correctness and containment over cold-start latency.

Those are deliberate. See [ARCHITECTURE.md](ARCHITECTURE.md) for the reasoning.
None of these are gaps waiting to be filled. They are the boundary that keeps
openblox small enough to be worth reading, and requests to cross it get declined
on that basis. See [ARCHITECTURE.md](ARCHITECTURE.md) for the reasoning.

## Install

Expand Down
26 changes: 26 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,29 @@ kernel with the host.
openblox takes the third option: a substrate small enough to read in an afternoon, that
you run yourself, with isolation supplied by gVisor rather than by hope.

## Where this sits

openblox is the layer *below* a sandbox platform, not a smaller one.

```
your scheduler, your tenancy, your API ← yours to build, if you ever need it
──────────────────────────────────────
openblox ← isolation, done correctly
──────────────────────────────────────
Docker + gVisor ← the boundary itself
```

!!! quote "The rule"
**How a sandbox is isolated is openblox's problem.
Which sandbox runs where is yours.**

Egress, capabilities, filesystem, resource caps, lifetime, runtime: openblox's.
Placement, queueing, tenancy, metering, snapshots: not openblox's, and not planned.
Build those on top when something actually asks for them. That is what a lower layer
is for, and it is why there is no control plane to adopt first.

The comparison is `libvirt`, not OpenStack.

## What you get

<div class="grid cards" markdown>
Expand Down Expand Up @@ -73,6 +96,9 @@ you run yourself, with isolation supplied by gVisor rather than by hope.
- **Not a substitute for a threat model.** Read the [security model](security.md) and
decide whether its guarantees match your workload.

The first two are the rule above, applied: they are placement, not isolation. They
are not gaps waiting to be filled.

## Next

- [Quick start](getting-started.md) — install, prerequisites, a working example
Expand Down
Loading