# First Steps

> Cordium documentation. Canonical page: <https://octelium.com/docs/cordium/latest/overview/first-steps>.

This guide walks you through the essentials of Cordium in about 15 minutes: running your first *Workspace*, executing commands inside it, defining a reusable *Template* with a *Secret*, accessing an Octelium *Service* without any credentials, and checkpointing a *Workspace* with a snapshot. It assumes that you already have a Cordium *Cluster* (see the [quick installation guide](https://octelium.com/docs/cordium/latest/overview/quick-install.md)) and that you have installed the `cordium` and `octelium` CLIs (see [here](https://octelium.com/docs/cordium/latest/install/cli.md)).

## Log in to the Cluster

Cordium uses your Octelium identity. The `cordium` CLI shares its authentication state with the `octelium` and `octeliumctl` CLIs, so you only need to log in once. If you are not already logged in, any `cordium` command opens a browser window for you to authenticate via the *Cluster*'s identity providers:

```bash
export OCTELIUM_DOMAIN=<DOMAIN>

# Log in via your web identity provider
octelium login
# OR via an authentication token Credential
octelium login --auth-token <AUTHENTICATION_TOKEN>

# Show your User, Session and Cluster information
cordium status
```

## Run Your First Workspace

The `cordium run` command creates a *Workspace*, starts it, waits for it to be ready and opens an interactive terminal inside it, all in one step:

```bash
cordium run --image node:24-bookworm
```

The CLI shows the *Workspace*'s state as it moves through its lifecycle (e.g. `INITIALIZING`, `PULLING_IMAGE`, `STARTING_RUNTIME`, `PREPARING`) and then drops you into a shell inside the sandbox. From there, you have a full Linux environment with `sudo`:

```bash
node --version
sudo apt-get update && sudo apt-get install -y ripgrep
echo $CORDIUM_NAME
```

The `CORDIUM_NAME` environment variable holds the *Workspace*'s randomly generated name (e.g. `x7k2`). Exit the shell with `exit` or `Ctrl+D`; the *Workspace* keeps running until you stop it, or until it stops itself after a period of inactivity.

You can now list your *Workspaces* from your own machine:

```bash
cordium get workspace
# Or simply
cordium get ws
```

The output looks as follows:

```text
┌──────┬─────────┬──────────┬───────────────┬─────────┬──────────────┐
│ NAME │ CREATED │ TEMPLATE │     SPACE     │  STATE  │ LAST STARTED │
├──────┼─────────┼──────────┼───────────────┼─────────┼──────────────┤
│ x7k2 │ 4m12s   │ default  │ default       │ RUNNING │ 4m12s        │
└──────┴─────────┴──────────┴───────────────┴─────────┴──────────────┘
```

Since the *Workspace* was created without a *Template* or a *Space*, it belongs to the `default` *Template* of your `default` *Space*, which is automatically created for you.

## Run Commands from Your Machine

You don't need a terminal session to use a *Workspace*. The `cordium exec` command runs a single command inside it and streams its output back, while propagating its exit code, which makes it ideal for scripts and AI agents:

```bash
cordium exec x7k2 -- node -e "console.log(6 * 7)"
cordium exec x7k2 -w /tmp -- sh -c "git clone https://github.com/expressjs/express && cd express && npm install --silent && npm test"
```

You can also copy files to and from the *Workspace* and SSH into it from any SSH client, including VS Code and Zed (read more [here](https://octelium.com/docs/cordium/latest/use/ssh.md)):

```bash
# The SSH-based commands require you to be connected to the Cluster
octelium connect -d

cordium cp ./notes.md x7k2:/workspace/notes.md
cordium ssh x7k2
```

## Define a Template

Typing flags gets old quickly. A *Template* captures a reusable *Workspace* configuration inside a *Space*. Let's create a personal *Space* named `tutorial`, a *Secret* inside it, and a *Template* for a Node.js project. In this guide, we assume that your Octelium *User* name is `alice` (you can see yours via `cordium status`), which means that the full name of the `tutorial` *Space* is `tutorial.alice`:

```bash
cordium create space tutorial
# Enter any value (e.g. a GitHub token) when prompted
cordium create secret npm-token.tutorial
```

Now create a file named `express.yaml` as follows:

```yaml
spec:
  image:
    registry:
      url: node:24-bookworm
  repository:
    url: https://github.com/expressjs/express
    cloneOptions:
      branch: master
  runtime:
    envVars:
      - key: NODE_ENV
        value: development
      - key: NPM_TOKEN
        fromSecret: npm-token.tutorial.alice
    tasks:
      - name: install
        type: ON_CREATE
        workingDir: /workspace/repo
        run: npm install
        onFailure: ON_FAILURE_ABORT
      - name: tests
        type: POST_START
        workingDir: /workspace/repo
        run: npm test
  limit:
    cpu:
      millicores: 2000
    memory:
      megabytes: 4096
```

And create the *Template* out of it:

```bash
cordium create template express.tutorial --file express.yaml
```

Every *Workspace* created from this *Template* now clones the repository into `/workspace/repo`, installs its dependencies the first time it starts, runs the tests on every start and gets the `NPM_TOKEN` environment variable from the *Secret*, which is referred to by its full name (i.e. `npm-token.tutorial.alice`):

```bash
cordium run --template express.tutorial
```

You can follow the initialization logs, including the output of the tasks, from another terminal:

```bash
cordium logs <WORKSPACE>
```

> **Note:**
>
> Read in detail about all the *Workspace* configuration options [here](https://octelium.com/docs/cordium/latest/workspaces/overview.md). You can also pre-build *Templates* so that their *Workspaces* start with all dependencies already installed (read more [here](https://octelium.com/docs/cordium/latest/workspaces/templates.md#pre-builds)).

## Access an Octelium Service Without Credentials

Every *Workspace* is an Octelium identity that automatically connects to the *Cluster*. This means that it can access the Octelium *Services* that you are authorized to access by their names, without any API key, password, private key or kubeconfig inside it. The quick installer creates a `demo-nginx` *Service* that you can try right away from any *Workspace*:

```bash
cordium exec x7k2 -- curl -s http://demo-nginx
```

Now let's protect a real resource. The following Octelium *Service* exposes a PostgreSQL database whose password is stored as an Octelium *Secret* that never leaves the *Cluster* (read more about PostgreSQL *Services* [here](https://octelium.com/docs/octelium/latest/management/core/service/postgres.md)):

```bash
octeliumctl create secret pg-password
```

```yaml
kind: Service
metadata:
  name: pg-staging
spec:
  mode: POSTGRES
  port: 5432
  config:
    upstream:
      url: postgres://pg-staging.example.com
    postgres:
      user: app_readonly
      database: app
      sslMode: REQUIRE
      auth:
        password:
          fromSecret: pg-password
```

Apply it via `octeliumctl apply` and use it from inside any of your *Workspaces* with no credentials at all:

```bash
psql -h pg-staging -c "SELECT now();"
```

Every query is authorized by Octelium *Policies* and audited via OpenTelemetry-native access logs. Read more about secretless access from *Workspaces* [here](https://octelium.com/docs/cordium/latest/workspaces/secretless.md).

## Snapshot, Stop and Clean Up

Before doing something risky (e.g. letting an AI agent loose on your repository), you can take a snapshot of a *Workspace* and later restore it into a new one:

```bash
cordium create snapshot before-agent --workspace x7k2
cordium get snapshot
# Restore it into a brand new Workspace once it is READY
cordium run --snapshot before-agent
```

> **Note:**
>
> Snapshots and *Template* pre-builds require a storage backend that supports Kubernetes CSI volume snapshots (e.g. Longhorn via the `--longhorn` flag of the quick installer). Read more [here](https://octelium.com/docs/cordium/latest/workspaces/snapshots.md).

Finally, stop and delete your *Workspaces* when you're done:

```bash
cordium stop x7k2
cordium delete workspace x7k2
```

## Where to Go Next

- Explore the [web portal](https://octelium.com/docs/cordium/latest/use/web-portal.md) and chat with the [Cordium Agent](https://octelium.com/docs/cordium/latest/use/agent.md).
- Learn every [CLI command](https://octelium.com/docs/cordium/latest/use/cli.md) and the [SDKs](https://octelium.com/docs/cordium/latest/use/api.md) for Go, Python, Rust and TypeScript.
- Run [Claude Code](https://octelium.com/docs/cordium/latest/examples/ai/claude-code.md) or [Codex](https://octelium.com/docs/cordium/latest/examples/ai/codex.md) unattended in ephemeral *Workspaces*.
- Share data between *Workspaces* via [Volumes](https://octelium.com/docs/cordium/latest/workspaces/volumes.md) and [SSH](https://octelium.com/docs/cordium/latest/examples/workflows/ssh-cp.md).
