Repository navigation
Add Secure Agent Workspace pattern docs #734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
laubai
merged 3 commits into
validatedpatterns:main
from
sauagarwa:secure-agent-workspace-docs
Oct 6, 2026
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| --- | ||
| title: Secure Agent Workspace | ||
| date: 2026-09-30 | ||
| tier: sandbox | ||
| summary: This pattern gives each user an isolated AI agent workspace in their own OpenShift Virtualization VM, running NVIDIA OpenShell and OpenClaw agents with OIDC sign-in, governed sandbox policy, and API keys kept in Vault. | ||
| rh_products: | ||
| - Red Hat OpenShift Container Platform | ||
| - Red Hat OpenShift Virtualization | ||
| - Red Hat OpenShift GitOps | ||
| - Red Hat build of Keycloak | ||
| partners: | ||
| - NVIDIA | ||
| industries: | ||
| - General | ||
| focus_areas: | ||
| - AI | ||
| - Security | ||
| - Virtualization | ||
| aliases: /secure-agent-workspace/ | ||
| links: | ||
| github: https://github.com/validatedpatterns-sandbox/secure-agent-workspace | ||
| install: getting-started | ||
| arch: /images/secure-agent-workspace/saw-architecture.png | ||
| bugs: https://github.com/validatedpatterns-sandbox/secure-agent-workspace/issues | ||
| feedback: https://docs.google.com/forms/d/e/1FAIpQLScI76b6tD1WyPu2-d_9CCVDr3Fu5jYERthqLKJDUGwqBg7Vcg/viewform | ||
| --- | ||
| :toc: | ||
| :imagesdir: /images | ||
| :_content-type: ASSEMBLY | ||
| include::modules/comm-attributes.adoc[] | ||
|
|
||
| include::modules/secure-agent-workspace-about.adoc[leveloffset=+1] | ||
|
|
||
| include::modules/secure-agent-workspace-architecture.adoc[leveloffset=+1] | ||
|
|
||
| [id="next-steps-secure-agent-workspace"] | ||
| == Next steps | ||
|
|
||
| * link:getting-started[Getting started] | ||
| * link:cluster-sizing[Cluster sizing] | ||
| * link:ideas-for-customization[Ideas for customization] | ||
| * link:troubleshooting[Troubleshooting] |
68 changes: 68 additions & 0 deletions
68
content/patterns/secure-agent-workspace/cluster-sizing.adoc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| --- | ||
| title: Cluster sizing | ||
| weight: 20 | ||
| aliases: /secure-agent-workspace/cluster-sizing/ | ||
| --- | ||
|
|
||
| :toc: | ||
| :imagesdir: /images | ||
| :_content-type: ASSEMBLY | ||
| include::modules/comm-attributes.adoc[] | ||
| include::modules/secure-agent-workspace/metadata-secure-agent-workspace.adoc[] | ||
|
|
||
| [id="secure-agent-workspace-bare-metal"] | ||
| == Hardware virtualization requirements | ||
|
|
||
| Each workspace is a {VirtProductName} virtual machine. {VirtProductName} uses the hardware virtualization of the node (Intel VT-x or AMD-V through KVM), so the worker nodes that run the workspace VMs must be bare metal: | ||
|
|
||
| * *On premises*: {ocp} installed on bare-metal servers, with virtualization enabled in the firmware. | ||
| * *Public cloud*: bare-metal instance types, for example `m5.metal`, `m6i.metal`, or `c5n.metal` on {AWS}. Virtualized instance types cannot run the VMs, because nested virtualization is not supported. | ||
|
|
||
| The control plane nodes can be virtual machines or virtualized instances. For the full list of requirements, see link:https://docs.redhat.com/en/documentation/openshift_container_platform/latest/html/virtualization/installing#preparing-cluster-for-virt[Preparing your cluster for OpenShift Virtualization]. | ||
|
|
||
| [id="secure-agent-workspace-sizing"] | ||
| == Sizing requirements | ||
|
|
||
| Size the bare-metal workers for the shared services plus one VM per user. Each VM requests its full memory from the node, so the amount of memory on the node limits the number of workspaces the node can run. | ||
|
|
||
| .Resources per component | ||
| [cols="2,1,1,1",options="header"] | ||
| |=== | ||
| | Component | vCPU | Memory | Storage | ||
|
|
||
| | Shared services: Operators, Argo CD, Keycloak and its database, Vault, governance interceptor | ||
| | 8 | ||
| | 16 GiB | ||
| | 50 GiB, including the template VM image | ||
|
|
||
| | Each workspace VM (default, set in the `openshell-saw` chart as `vm.cores`, `vm.memory`, `vm.diskSize`) | ||
| | 4 | ||
| | 8 GiB | ||
| | 40 GiB | ||
| |=== | ||
|
|
||
| .Example minimum cluster | ||
| [cols="<,^,<",options="header"] | ||
| |=== | ||
| | Node type | Number of nodes | Example (AWS) | ||
|
|
||
| | Control plane | ||
| | 3 | ||
| | `m5.xlarge` | ||
|
|
||
| | Bare-metal worker | ||
| | 2 | ||
| | `m5.metal` (96 vCPU, 384 GiB memory) | ||
| |=== | ||
|
|
||
| Two bare-metal workers of this size hold the shared services and dozens of workspaces. With smaller servers, plan for the shared services plus 4 vCPU and 8 GiB of memory per user. Ensure that there is room to move VMs from one node to another in case of node failure. | ||
|
|
||
| [id="secure-agent-workspace-storage"] | ||
| == Storage requirements | ||
|
|
||
| The cluster needs a default storage class for the VM disks (`ReadWriteOnce`, 40 GiB per user by default) and for the template image that the disks are cloned from. Storage that supports smart cloning, such as {rh-ocp-data-first} or a CSI driver with volume snapshots, makes new workspaces start faster. | ||
|
|
||
| [id="secure-agent-workspace-model-serving"] | ||
| == Model serving | ||
|
|
||
| By default, the agents use NVIDIA Nemotron on build.nvidia.com and need no GPU in the cluster. If you serve models on the cluster instead, for example with vLLM, add the GPU nodes that the model server needs. For more information, see link:ideas-for-customization[Ideas for customization]. |
275 changes: 275 additions & 0 deletions
275
content/patterns/secure-agent-workspace/getting-started.adoc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,275 @@ | ||
| --- | ||
| title: Getting started | ||
| weight: 10 | ||
| aliases: /secure-agent-workspace/getting-started/ | ||
| --- | ||
|
|
||
| :toc: | ||
| :imagesdir: /images | ||
| :_content-type: ASSEMBLY | ||
| include::modules/comm-attributes.adoc[] | ||
|
|
||
| [id="deploying-secure-agent-workspace-pattern"] | ||
| == Deploying the Secure Agent Workspace pattern | ||
|
|
||
| .Prerequisites | ||
|
|
||
| * An {ocp} cluster with *bare-metal worker nodes* to provide hardware virtualization to run a separate {VirtProductName} VM for each workspace. {VirtProductName} does not support nested virtualization. | ||
| ** *For on-premises deployments*, install {ocp} on bare-metal servers with Intel VT-x or AMD-V enabled in the firmware. | ||
| ** *For public cloud deployments*, select bare-metal instance types for workers, for example, on AWS, select `m5.metal` or `c5n.metal`. | ||
| ** See link:cluster-sizing[Cluster sizing] for advice on the size and number of nodes required. | ||
| ** You can create an {ocp} cluster by using the link:https://console.redhat.com/openshift/create[Red{nbsp}Hat Hybrid Cloud Console]. | ||
| * A default storage class that can provision `ReadWriteOnce` volumes for the VM disks. | ||
| * Cluster administrator access. End users need no {ocp} access: they sign in to the workspaces with Keycloak. | ||
| * An API key for each service that the default profile uses: build.nvidia.com (NVIDIA Nemotron) and Brave Search. To use a model server of your own instead, see link:ideas-for-customization[Ideas for customization]. | ||
| * The `oc` CLI. For instructions, see link:https://docs.openshift.com/container-platform/latest/cli_reference/openshift_cli/getting-started-cli.html[Getting started with the OpenShift CLI]. | ||
| * The Helm binary. For instructions, see link:https://helm.sh/docs/intro/install/[Installing Helm]. | ||
| * The `openshell` CLI, version 0.1.x, from the link:https://github.com/NVIDIA/OpenShell/releases[OpenShell releases]. A 0.0.x CLI cannot connect to the 0.1.x gateway that this pattern installs. | ||
| * Additional installation tool dependencies. For details, see link:https://validatedpatterns.io/learn/quickstart/[Patterns quick start]. | ||
|
|
||
| [id="preparing-for-deployment-saw"] | ||
| == Preparing for deployment | ||
| .Procedure | ||
|
|
||
| . Fork the link:https://github.com/validatedpatterns-sandbox/secure-agent-workspace[secure-agent-workspace] repository on GitHub. You must fork the repository to add users and to customize this pattern. | ||
|
|
||
| . Clone the forked copy of this repository. | ||
| + | ||
| [source,terminal,subs="+quotes"] | ||
| ---- | ||
| $ git clone git@github.com:__<your-username>__/secure-agent-workspace.git | ||
| ---- | ||
|
|
||
| . Go to the root directory of your Git repository: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ cd secure-agent-workspace | ||
| ---- | ||
|
|
||
| . Run the following command to set the upstream repository: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ git remote add -f upstream git@github.com:validatedpatterns-sandbox/secure-agent-workspace.git | ||
| ---- | ||
|
|
||
| . Generate the SSH key pair that the pattern uses to reach the workspace VMs for troubleshooting: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ make generate-keys | ||
| ---- | ||
| + | ||
| The keys are written to `~/.generated-ssh-keys/`. | ||
|
|
||
| . Save your API keys in files outside the repository, one key per line: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ echo '<build.nvidia.com API key>' > ~/.nvidia-api-key | ||
| $ echo '<Brave Search API key>' > ~/.brave-api-key | ||
| $ chmod 600 ~/.nvidia-api-key ~/.brave-api-key | ||
| ---- | ||
|
|
||
| . Make a local copy of the secrets template outside your repository to hold credentials for the pattern. | ||
| + | ||
| [WARNING] | ||
| ==== | ||
| Do not add, commit, or push this file to your repository. Doing so might expose personal credentials to GitHub. | ||
| ==== | ||
| + | ||
| Run the following command: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ cp values-secret.yaml.template ~/values-secret-secure-agent-workspace.yaml | ||
| ---- | ||
| + | ||
| The template reads the SSH keys and the two API key files from the paths above. Edit your copy of the secrets file to store your API key files in a different location, or to use a different model provider. | ||
|
|
||
| . Optional: Choose who gets a workspace. Edit `overrides/saw-users.yaml`. Each entry in the `users` list defines one user. The `name` of each user is also used for that user's namespace and for their VM: | ||
| + | ||
| [source,yaml] | ||
| ---- | ||
| users: | ||
| - name: alice | ||
| profiles: | ||
| - data-science | ||
| ---- | ||
| + | ||
| The name must also be a user in Keycloak. The pattern's realm includes the test users `alice` and `bob`. Each name must be a lowercase DNS label no more than 19 characters long. | ||
|
|
||
| . Optional: To customize the deployment, create and switch to a new branch by running the following command: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ git checkout -b my-branch | ||
| ---- | ||
| + | ||
| Make your changes, then stage, commit, and push them: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ git add <changed-files> | ||
| $ git commit -m "Customize deployment" | ||
| $ git push origin my-branch | ||
| ---- | ||
| + | ||
| The branch that you deploy must exist on your fork, because {rh-gitops} syncs from it. | ||
|
|
||
| [id="deploying-cluster-using-patternsh-file-saw"] | ||
| == Deploying the pattern by using the pattern.sh file | ||
|
|
||
| To deploy the pattern by using the `pattern.sh` file, complete the following steps: | ||
|
|
||
| . Log in to your cluster. | ||
|
|
||
| .. Obtain an API token by visiting `https://oauth-openshift.apps.<your_cluster>.<domain>/oauth/token/request`. | ||
|
|
||
| .. Log in to the cluster by running the following command: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ oc login --token=<retrieved-token> --server=https://api.<your_cluster>.<domain>:6443 | ||
| ---- | ||
| + | ||
| Or log in by running the following command: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ export KUBECONFIG=~/<path_to_kubeconfig> | ||
| ---- | ||
|
|
||
| . Copy the prebuilt template VM image into the cluster's internal registry. This takes about 5 minutes: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ make copy-images | ||
| ---- | ||
|
|
||
| . Deploy the pattern to your cluster. Run the following command: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ ./pattern.sh make install | ||
| ---- | ||
| + | ||
| To deploy a branch other than the one that is checked out, export `TARGET_BRANCH` before you run the command, and `TARGET_ORIGIN` if the branch is on a remote other than `origin`. For example: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ export TARGET_BRANCH=my-branch | ||
| $ export TARGET_ORIGIN=origin | ||
| $ ./pattern.sh make install | ||
| ---- | ||
|
|
||
| .Verification | ||
|
|
||
| . Check the health of the Argo CD applications: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ ./pattern.sh make argo-healthcheck | ||
| ---- | ||
| + | ||
| It might take 20 to 30 minutes for all applications to synchronize, the Operators to install, and the first workspace VM to boot. | ||
|
|
||
| . Verify that the Operators are installed. In the {ocp} web console, go to *Operators \-> Installed Operators* and confirm that the following Operators are present: | ||
| + | ||
| * {VirtProductName} | ||
| * Red{nbsp}Hat build of Keycloak | ||
| * {eso} | ||
|
|
||
| . Verify that each user's VM is running. For the user `alice`: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ oc get vm -n saw-alice | ||
| ---- | ||
| + | ||
| .Example output | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| NAME AGE STATUS READY | ||
| alice 12m Running True | ||
| ---- | ||
|
|
||
| . Check that the installer in the VM finished. Both steps must show `"phase": "Done"`: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ make openshell-saw-status OPENSHELL_SAW_NAME=alice | ||
| ---- | ||
| + | ||
| To follow the installer as it runs, use `make openshell-saw-logs OPENSHELL_SAW_NAME=alice`. | ||
|
|
||
| [id="accessing-a-workspace-saw"] | ||
| == Accessing a workspace | ||
|
|
||
| . Register the user's gateway and log in. | ||
| + | ||
| Run the following commands, then use the browser window that opens to log in using Keycloak. The test user is `alice` with password `alice`. | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ export OPENSHELL_SAW_NAME=alice | ||
| $ make openshell-saw-configure-gateway | ||
| $ openshell gateway login alice | ||
| ---- | ||
|
|
||
| . List the sandboxes of the default profile: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ openshell sandbox list | ||
| $ openshell sandbox list --workspace cuda-dev | ||
| ---- | ||
| + | ||
| .Example output | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| NAME CREATED PHASE | ||
| notebook 2026-09-30 14:40:42 Ready | ||
| ---- | ||
|
|
||
| . Open the OpenClaw agent in the `notebook` sandbox, in the terminal or in the browser: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ make openclaw-tui SANDBOX_NAME=notebook | ||
| $ make openclaw-gui SANDBOX_NAME=notebook GUI_PORT=28789 | ||
| ---- | ||
| + | ||
| The browser UI opens through an SSH tunnel on `http://localhost:28789`. | ||
|
|
||
| . Open the OpenShell web UI, which lists the user's workspaces and sandboxes: | ||
|
sauagarwa marked this conversation as resolved.
|
||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ oc get route alice-webui -n saw-alice -o jsonpath='https://{.spec.host}{"\n"}' | ||
| ---- | ||
|
|
||
| . Optional: See the sandbox policy in effect. GitHub is not one of the hosts that the default profile allows, so the sandbox's egress proxy blocks the agent's request. In the OpenClaw agent of the `notebook` sandbox, enter the following prompt: | ||
| + | ||
| [source,text] | ||
| ---- | ||
| Use your terminal tool to run curl -sS --max-time 10 https://api.github.com/zen. Show the command and its exact output. | ||
| ---- | ||
| + | ||
| The command fails because the connection is denied. To see the denial, view the sandbox logs: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ openshell --gateway alice --workspace default \ | ||
| logs notebook --since 5m --source sandbox | ||
| ---- | ||
|
|
||
| [id="next-steps-getting-started-saw"] | ||
| == Next steps | ||
|
|
||
| * link:ideas-for-customization[Ideas for customization] | ||
| * link:cluster-sizing[Cluster sizing] | ||
| * link:troubleshooting[Troubleshooting] | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are several procedures in this file that can be split out into separate modules, but I'm happy to do that part after this is merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @laubai .