Freestyle Docs

Freestyle / Docs

Client Sessions

Let end users operate an existing VM with scoped identity tokens.

Freestyle identities let an end user or agent operate an existing VM without receiving your team API key. Your server creates an identity, grants access to specific VMs and Linux users, mints a token, and sends only that token to the client.

Issue A Client Token

import { Freestyle } from "freestyle";

const freestyle = new Freestyle();
const { vm, vmId } = await freestyle.vms.create({
  // Required: a VM reaches nothing it has not been allowed to.
  firewall: { rules: [{ action: "allow", source: {}, destination: { public: true } }] },
});

await vm.exec(`
  id developer >/dev/null 2>&1 || useradd --create-home --shell /bin/bash developer
`);

const { identity, identityId } = await freestyle.identities.create();
await identity.permissions.vm.grant({
  vmId,
  allowedLinuxUsers: ["developer"],
});

const { id: tokenId, token } = await identity.tokens.create();

return { identityId, tokenId, token, vmId };

The token value is returned only when it is created. Store it securely or send it directly to its intended client.

Use The Token In A Client

import { Freestyle } from "freestyle";

const freestyle = new Freestyle({
  identityAccessToken: token,
});

const vm = freestyle.vms.ref(vmId);
const developer = vm.linuxUser("developer");
const result = await developer.exec("whoami");
console.log(result.stdout);

const shell = await developer.pty.open({
  onData: (bytes) => console.log(new TextDecoder().decode(bytes)),
});

An identity-token client is limited to the VM permissions granted to that identity. It cannot create arbitrary team resources.

Manage Grants And Tokens

const grants = await identity.permissions.vm.list();
const grant = await identity.permissions.vm.get(vmId);

await identity.permissions.vm.update(vmId, ["developer", "runner"]);
await identity.permissions.vm.revoke(vmId);

const tokens = await identity.tokens.list();
await identity.tokens.revoke(tokenId);

Use null as the second argument to permissions.vm.update() for unrestricted Linux-user access. Revoking a token or VM grant takes away that access without exposing or rotating your team API key.

Identity Lifecycle

const { identities, total } = await freestyle.identities.list({ limit: 50 });
const current = await freestyle.identities.get(identityId);
await freestyle.identities.delete(identityId);

Deleting an identity also deletes its tokens and grants. Managed identities cannot be deleted through this API.

esc