# Personal Configuration

> Cordium documentation. Canonical page: <https://octelium.com/docs/cordium/latest/workspaces/user-config>.

Every *User* has a *UserConfig* that personalizes all of their *Workspaces*, regardless of the *Space* or the *Template* that they belong to, together with *UserSecrets* which hold their personal credentials. Both are private to the *User*: *Space* admins cannot see nor modify them.

## UserConfig

The *UserConfig* is created automatically and can be edited from the **Settings** page of the web portal or via the `GetUserConfig` and `UpdateUserConfig` APIs. Here is an example:

```yaml
spec:
  dotfiles:
    url: https://github.com/alice/dotfiles
    branch: main
  envVars:
    - key: EDITOR
      value: nvim
    - key: GH_TOKEN
      fromUserSecret: github-pat.alice
  tasks:
    - name: starship
      type: ON_CREATE
      run: curl -sS https://starship.rs/install.sh | sh -s -- -y -b ~/.local/bin
  preferredRegion: eu-west
```

| Field             | Description                                                                                                                                                                                                                             |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dotfiles`        | Your dotfiles repository (see below).                                                                                                                                                                                                   |
| `envVars`         | Environment variables injected into all your *Workspaces*, with static values or values sourced from your *UserSecrets* via their full name (i.e. `<NAME>.<USER>`). They have the lowest precedence among all the configuration levels. |
| `tasks`           | Personal lifecycle tasks that run in all your *Workspaces*, after the *Template*'s and the *Workspace*'s tasks and before the *Space*'s tasks.                                                                                          |
| `preferredRegion` | The *Region* in which your *Workspaces* run by default, unless their storage, *Volumes* or snapshots require another *Region*.                                                                                                          |

### Dotfiles

Your dotfiles repository is cloned into `~/dotfiles` on the fresh runs of every *Workspace*, including *Workspaces* restored from *Template* pre-builds. Cordium then runs the first executable script that it finds among the following paths of the repository, as the *Workspace* user and with a timeout of 3 minutes:

```text
install.sh
install
bootstrap.sh
bootstrap
script/bootstrap
setup.sh
setup
script/setup
```

If no such script is found, the repository is only cloned. Here is an example of an `install.sh`:

```bash
#!/usr/bin/env bash
set -euo pipefail

DIR="$(cd "$(dirname "$0")" && pwd)"

ln -sf "$DIR/.gitconfig" ~/.gitconfig
ln -sf "$DIR/.tmux.conf" ~/.tmux.conf
mkdir -p ~/.config && ln -sf "$DIR/nvim" ~/.config/nvim

if command -v zsh >/dev/null; then
  sudo chsh -s "$(command -v zsh)" "$(whoami)"
fi
```

For private dotfiles repositories, use HTTP basic authentication with a *UserSecret*:

```yaml
spec:
  dotfiles:
    url: https://github.com/alice/dotfiles-private
    authentication:
      http:
        username: alice
        password:
          fromUserSecret: dotfiles-token.alice
```

> **Note:**
>
> Dotfiles are not applied to *Template* pre-builds, which are shared among all the *Users* of the *Template*, nor to *Workspaces* restored from *WorkspaceSnapshots*, whose storage already contains them.

## UserSecrets

*UserSecrets* are personal credentials that are only usable by their owner. Like *Space* *Secrets*, their values are write-only. You can manage them from the web portal or via the CLI:

```bash
# Enter the value interactively
cordium create usersecret github-pat

# From a flag, a file or an environment variable
cordium create usersecret openai-key --value "sk-..."
cordium create usersecret gpg-key --file ./private.asc
cordium create usersecret github-pat --from-env GITHUB_TOKEN

cordium get usersecret
cordium delete usersecret github-pat
```

*UserSecrets* are used as the sources of the *UserConfig*'s environment variables and of the dotfiles repository's password.

### SSH Keys

*UserSecrets* of the `SSH_KEY` type are ECDSA key pairs that are generated by the *Cluster*:

```bash
cordium create usersecret github-ssh --type ssh-key
cordium get usersecret github-ssh -o yaml
```

The public key is available in the *UserSecret*'s `status.sshKey.publicKey` field, which you can register at GitHub, GitLab or any SSH server. The private key, on the other hand, never enters your *Workspaces*. Instead, every *Workspace* runs an SSH agent outside of its sandbox that holds the private keys of all your `SSH_KEY` *UserSecrets*, and exposes it inside the *Workspace* via the `SSH_AUTH_SOCK` environment variable. As a result, `ssh` and `git` over SSH work out of the box inside all your *Workspaces*:

```bash
ssh-add -l
git clone git@github.com:acme-corp/payments-api.git
```

You can also use the same key to sign your commits:

```bash
git config --global gpg.format ssh
git config --global user.signingkey "key::$(ssh-add -L | head -n 1)"
git config --global commit.gpgsign true
```

> **Note:**
>
> Processes inside the *Workspace* can use the SSH agent to sign while the *Workspace* is running, but they can never extract the private key. Deleting the *UserSecret* removes the key from all your *Workspaces* on their next run.
