---
title: "SSH Access"
description: "SSH into Freestyle VMs with scoped identity tokens."
url: "/docs/vms/ssh"
---

Freestyle VMs accept SSH through `vm-ssh.freestyle.sh`. Access is controlled with Freestyle identities and tokens.


## SSH Format

```bash
ssh <vm-id>@vm-ssh.freestyle.sh
ssh <vm-id>:<access-token>@vm-ssh.freestyle.sh
ssh <vm-id>+<linux-user>:<access-token>@vm-ssh.freestyle.sh
```

If you omit the token from the SSH URL, SSH prompts for it as the password.


## Create A Token

```ts
import { freestyle } from "freestyle";

const { vm, vmId } = await freestyle.vms.create();

const { identity } = await freestyle.identities.create();
await identity.permissions.vms.grant({
  vmId,
});

const { token } = await identity.tokens.create();

console.log(`ssh ${vmId}:${token}@vm-ssh.freestyle.sh`);
```


## SSH As A Linux User

Create the VM with the users your application needs, then grant access to a specific user.

```ts
const { vmId } = await freestyle.vms.create({
  users: [{ name: "developer" }, { name: "reviewer" }],
});

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

const { token } = await identity.tokens.create();

console.log(`ssh ${vmId}+developer:${token}@vm-ssh.freestyle.sh`);
```


## Multiple Developers

Create separate identities when different users or agents should have different VM permissions.

```ts
const { identity: alice } = await freestyle.identities.create();
await alice.permissions.vms.grant({
  vmId,
  allowedUsers: ["alice"],
});

const { identity: bob } = await freestyle.identities.create();
await bob.permissions.vms.grant({
  vmId,
  allowedUsers: ["bob"],
});
```

Keep your Freestyle API key server-side. Send only scoped access tokens to clients or developers.
