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.