Skip to content

Credentials and bindings

Archil is built for objects your app creates while it runs: a disk per user, a branch per session, a sandbox per task. Alchemy splits the API in two to match.

The few long-lived things an app shares are resources in your Stack: a dataset disk, a seeded base, an image, a dev box.

src/Storage.ts
export const Dataset = Archil.Disk("Dataset", {});
export const Agent = Archil.Image("Agent", { image: "node:24-bookworm" });

They deploy, update, and delete with the Stack like any other resource.

Everything per user or per request comes from a binding. CreateDisk, CreateSandbox, and CreateImage create objects by name, with the same props the resources take:

const disks = yield* Archil.CreateDisk();
const home = yield* disks.create("user-1");

Bindings that take a resource act on it: ExecDisk(Dataset), ReadDisk(Dataset), BranchDisk(Seed), ConnectSandbox(DevBox), MountDisk(Dataset). Both kinds return the same disk and sandbox handles.

Objects created at run time are tagged with the stack, stage and binding (alchemy::stack, alchemy::stage, alchemy::id) and are not deleted when the stack is destroyed. List them by those tags to clean them up.

Archil disks and sandboxes have only a name, so the tags are a name prefix: alc-<id>-<hash of stack/stage/id>. Each Create… binding puts its prefix on every name it creates.

The client’s prefix is the value, and its list finds what carries it:

const disks = yield* Archil.CreateDisk();
for (const disk of yield* disks.list()) {
yield* disks.delete(disk.name.slice(disks.prefix.length + 1));
}

A host that only touches one disk never gets your API key. ReadDisk, WriteDisk and ReadWriteDisk give each host its own S3 user on the bound disk, read-only for ReadDisk. MountDisk(disk) on your own host gives it a mount token for the disk, read-only with mode: "read-only". In a program sandbox, the sandbox mounts the disk itself and no token is created.

Archil checks both itself, and destroying the stack revokes them.

Bindings that call Archil’s control plane (ExecDisk, CreateDisk, BranchDisk, CreateSandbox, ConnectSandbox, CreateImage) run with the API key you deploy with. Archil only creates API keys from the console and can’t scope them, so rotate yours there and redeploy.

A disk token opens one disk: home.createToken(name, { readOnly, expiresAt, oneUse }) makes one at run time for a machine that mounts with MountDisk(). A port token opens one port of one sandbox, for a browser or client that shouldn’t hold a key:

const token = yield* sandbox.createPortToken(8080, "1h");