---
title: SSH
icon: terminal
description: Mount a remote filesystem over SSH/SFTP.
---
The SSH resource mounts a remote server's filesystem over SFTP.
It supports full read and write operations.

## Config

```python
from mirage import MountMode, Workspace
from mirage.resource.ssh import SSHConfig, SSHResource

config = SSHConfig(
    host="myserver",
    username="deploy",
    identity_file="~/.ssh/id_ed25519",
    root="/var/data",
)
resource = SSHResource(config=config)
ws = Workspace({"/remote": resource}, mode=MountMode.WRITE)
```

| Field           | Required | Default | Description                          |
| --------------- | -------- | ------- | ------------------------------------ |
| `host`          | yes      |         | SSH host (name or IP)                |
| `hostname`      | no       |         | Override resolved hostname           |
| `port`          | no       | `22`    | SSH port                             |
| `username`      | no       |         | SSH username                         |
| `identity_file` | no       |         | Path to private key                  |
| `root`          | no       | `/`     | Remote directory to mount            |
| `timeout`       | no       | `30`    | Connection timeout in seconds        |
| `known_hosts`   | no       |         | Path to known_hosts file             |

The `host` field matches entries in `~/.ssh/config`, so existing SSH
configurations are automatically picked up.

## Filesystem Layout

```text
/remote/
  <remote-directory-tree>
```

The mounted tree mirrors the remote filesystem starting at `root`.

Example with `root="/var/data"`:

```text
/remote/
  logs/
    app.log
    nginx/
      access.log
      error.log
  config/
    app.yaml
  uploads/
    image.png
```

## Cache

Uses `IndexCacheStore` for directory listings. Freshness is checked
via `{mtime}:{size}` fingerprints - files are re-fetched only when
the remote has changed.

## Example

```python
import asyncio

from mirage import MountMode, Workspace
from mirage.resource.ssh import SSHConfig, SSHResource

config = SSHConfig(
    host="myserver",
    username="deploy",
    identity_file="~/.ssh/id_ed25519",
    root="/var/log",
)
resource = SSHResource(config=config)


async def main():
    ws = Workspace({"/logs": resource}, mode=MountMode.READ)

    # List remote directory
    r = await ws.execute("ls /logs/")
    print(await r.stdout_str())

    # Read last 20 lines of a log
    r = await ws.execute("tail -n 20 /logs/nginx/access.log")
    print(await r.stdout_str())

    # Search across log files
    r = await ws.execute('grep "ERROR" /logs/app.log')
    print(await r.stdout_str())

    # Find large files
    r = await ws.execute("find /logs/ -name '*.log'")
    print(await r.stdout_str())

    # File metadata
    r = await ws.execute("stat /logs/app.log")
    print(await r.stdout_str())


if __name__ == "__main__":
    asyncio.run(main())
```

## Shell Commands

| Command                | Notes                                      |
| ---------------------- | ------------------------------------------ |
| `ls`                   | List remote files and directories          |
| `cat`                  | Read remote file content                   |
| `head` / `tail`        | First/last N lines                         |
| `grep` / `rg`          | Pattern search (use targeted paths)        |
| `wc`                   | Line/word/byte counts                      |
| `stat`                 | File metadata (size, mtime)                |
| `find`                 | Recursive search with `-name`, `-maxdepth` |
| `tree`                 | Directory tree view                        |
| `mkdir`                | Create remote directories                  |
| `touch`                | Create empty remote files                  |
| `cp` / `mv` / `rm`    | Copy, move, delete on remote               |
| `tee`                  | Write stdin to remote file                 |
| `diff` / `cmp`         | Compare remote files                       |
| `sort` / `cut` / `tr`  | Text processing                            |
| `tar` / `zip` / `gzip` | Compression                                |
