--- title: Ideas for customization weight: 30 aliases: /secure-agent-workspace/ideas-for-customization/ --- :toc: :imagesdir: /images :_content-type: ASSEMBLY include::modules/comm-attributes.adoc[] [id="ideas-for-customization"] == Ideas for customizing the Secure Agent Workspace pattern Everything in this pattern is configured in Git: who gets a workspace, what each workspace contains, which providers and hosts agents can use, and which OpenShell release the VMs run. Commit and push a change to the branch that the pattern deploys, and {rh-gitops} applies it. [id="adding-users-saw"] === Adding and removing users Each entry in `overrides/saw-users.yaml` is one workspace: [source,yaml] ---- users: - name: alice profiles: - data-science - name: bob profiles: - data-science # Optional: vaultPrefix: secret/data/hub/saw-bob # bob's own API keys in Vault ownerSubject: # from `openshell whoami` after bob's first sign-in ---- * `name` is the user's Keycloak user name, the VM name, and the namespace suffix (`saw-`). It must be a lowercase DNS label of at most 19 characters. * `profiles` lists the SAW-BOM profiles the workspace gets (default: `data-science`). * `ownerSubject` makes that Keycloak user an administrator of the workspaces in the VM. * `vaultPrefix` points the workspace at its own API keys. Load them into {hashicorp-vault-short} under that prefix, as the commented example in `values-secret.yaml.template` shows. By default all workspaces share the keys under `secret/data/hub`. The pattern does not create Keycloak users. Create each user in the `openshell` realm of the Keycloak instance in the `saw-keycloak` namespace, and give them the `openshell-user` role. Removing an entry deletes that user's Argo CD applications but keeps the VM and the namespace. To delete them as well, first set `pruneOnRemove: true` on the entry and push, then remove the entry and push. [id="changing-profiles-saw"] === Changing what a workspace contains SAW-BOM profiles are directories in `charts/saw-bom/profiles///`, one per OpenShell workspace, with three files: `workspace.yaml`:: The workspace name and description. `providers.yaml`:: The providers: a type from the governance catalog, the Secret and key that hold the API key, and for model providers the model name. `sandbox.yaml`:: The sandboxes: name, type (`openclaw`, `nemoclaw`, or `generic`), container image, and the providers to attach. To add a profile, copy `data-science`, change it, and list it under `profiles` for the users that need it. A workspace VM applies profile changes on its next restart: [source,terminal] ---- $ make openshell-saw-restart OPENSHELL_SAW_NAME=alice ---- [id="changing-model-provider-saw"] === Changing the model provider The default profile uses NVIDIA Nemotron on build.nvidia.com. To use another provider, change the `inference` secret in your `values-secret` file (the `provider`, `model`, and `api_key` fields) and a matching provider in the profile. Then load the secrets again: [source,terminal] ---- $ ./pattern.sh make load-secrets ---- To use an alternative model server on your cluster, such as vLLM or Ollama, give users the `custom-inference` profile and complete the details of the `inference` example in `values-secret.yaml.template`. This section is commented out by default. You must specify `provider: openai`, and must provide valid values for the `model`, `url`, and `api_key` parameters. The URL must be reachable from the workspace VMs, for example a cluster Service. It cannot be `localhost`. [IMPORTANT] ==== Agents call the model endpoint directly, and the sandbox's egress proxy allows only the hosts that the provider profile names. For a custom endpoint, set the endpoint's `host` and `port` in `charts/governance-policy/profiles/openai.yaml`. Without that change, requests to your server are denied. ==== [id="changing-governance-saw"] === Changing the governance policy and provider profiles The governance interceptor serves two things from the `governance-policy` chart: `policy.yaml`:: The sandbox policy: filesystem paths that are read-only or writable, the user that agents run as, and Landlock settings. It applies to every sandbox. `profiles/.yaml`:: The provider profiles. You must define a provider profile in this directory before you can create a provider of that type. You cannot create providers whose type has no profile here. Each profile lists the credentials, the `endpoints` (hosts, ports, and protocols) that sandboxes can reach with it, and the `binaries` that can connect, for example `node` for OpenClaw or `curl`. For example, to let agents use GitHub, keep the `github` profile and add a provider of type `github` to a profile. To allow a new API, add a profile file with its hosts and binaries. [NOTE] ==== A profile that does not list `binaries` blocks all connections. List the real path of each program: the egress proxy resolves symbolic links before it matches a program, and you can use wildcards. For example, in the default image `/usr/bin/node` is a link to `/usr/bin/node-`, so for OpenClaw the profile must list `/usr/bin/node-*`. ==== Changes take effect when {rh-gitops} syncs the chart. Profile changes affect running sandboxes without restarting the sandbox. [id="upgrading-openshell-saw"] === Upgrading OpenShell The OpenShell release that the VMs run is pinned by image digest in the InstallerBOM, the `bom` block in `charts/openshell-saw/values.yaml`. To upgrade OpenShell, complete the following steps: . Change the component versions and digests in the `bom` block. All components (gateway, CLI, supervisor, and sandbox runtime) must come from the same release. . Build the governance interceptor from the same OpenShell release. It is set as `source.git.ref` in `image-builder-charts/helm/governance-interceptor-image/values.yaml`, and the chart's image tag must match. . Push, and restart the VMs. Each VM installs the new release on boot. [WARNING] ==== Updating to a new release series, for example from 0.0.x to 0.1.x, causes the gateway to lose its state, and the data in the `/sandbox` directory of each sandbox is lost. This occurs because the OpenShell installer moves the old gateway database aside and creates fresh workspaces, providers, and sandboxes. After an update to a new release series, users also need to update to a compatible version of the `openshell` CLI. ==== [id="optional-apf-saw"] === Additional customization options * *Custom container images*: sandbox images are set per sandbox in the profile's `sandbox.yaml`. The VM pulls them from their registry. * *Custom VM size*: `vm.cores`, `vm.memory`, and `vm.diskSize` in `charts/openshell-saw/values.yaml`, or per user under `values` in `overrides/saw-users.yaml`. * *Signing*: the installer can require signed OpenShell images (`signing.mode: enforce` in `charts/openshell-saw/values.yaml`) after the images you pin are signed.