diff --git a/.github/workflows/build-operator.yml b/.github/workflows/build-operator.yml index 1ac9e1583..99cc92b8c 100644 --- a/.github/workflows/build-operator.yml +++ b/.github/workflows/build-operator.yml @@ -83,6 +83,7 @@ jobs: - { suffix: "-pi", dockerfile: "Dockerfile.pi", artifact: "pi" } - { suffix: "-native", dockerfile: "Dockerfile.native", artifact: "native" } - { suffix: "-native-sandbox", dockerfile: "openshell/Dockerfile", artifact: "nativesandbox" } + - { suffix: "-kiro-sandbox", dockerfile: "openshell/Dockerfile.kiro", artifact: "kirosandbox" } platform: - { os: linux/amd64, runner: ubuntu-latest } - { os: linux/arm64, runner: ubuntu-24.04-arm } @@ -152,6 +153,7 @@ jobs: - { suffix: "-pi", artifact: "pi" } - { suffix: "-native", artifact: "native" } - { suffix: "-native-sandbox", artifact: "nativesandbox" } + - { suffix: "-kiro-sandbox", artifact: "kirosandbox" } runs-on: ubuntu-latest permissions: contents: read @@ -209,6 +211,7 @@ jobs: - { suffix: "-pi" } - { suffix: "-native" } - { suffix: "-native-sandbox" } + - { suffix: "-kiro-sandbox" } runs-on: ubuntu-latest permissions: contents: read diff --git a/.github/workflows/docker-smoke-test.yml b/.github/workflows/docker-smoke-test.yml index fd360c79e..4c6050aa9 100644 --- a/.github/workflows/docker-smoke-test.yml +++ b/.github/workflows/docker-smoke-test.yml @@ -4,6 +4,7 @@ on: pull_request: paths: - 'Dockerfile*' + - 'openshell/Dockerfile*' - 'src/**' - 'Cargo.*' @@ -25,6 +26,7 @@ jobs: - { dockerfile: Dockerfile.antigravity, suffix: "-antigravity", agent: "agy-acp", agent_args: "" } - { dockerfile: Dockerfile.pi, suffix: "-pi", agent: "pi-acp", agent_args: "" } - { dockerfile: openshell/Dockerfile, suffix: "-native-sandbox", agent: "openab-agent", agent_args: "" } + - { dockerfile: openshell/Dockerfile.kiro, suffix: "-kiro-sandbox", agent: "kiro-cli", agent_args: "acp --trust-all-tools" } runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 diff --git a/docs/adr/openshell-openab-preset-module.md b/docs/adr/openshell-openab-preset-module.md new file mode 100644 index 000000000..67ba9b102 --- /dev/null +++ b/docs/adr/openshell-openab-preset-module.md @@ -0,0 +1,161 @@ +# ADR: OpenShell OpenAB Day 1 Preset + +- **Status:** Discussion +- **Date:** 2026-06-10 +- **Updated:** 2026-06-25 +- **Author:** OpenAB POC contributors +- **Related:** [OpenShell quick start](../openshell.md), [Custom Gateway](./custom-gateway.md) + +## Context + +OpenAB can run through Kubernetes-style infrastructure or through NVIDIA OpenShell sandboxes. Kubernetes is operationally familiar but heavy. OpenShell is attractive for local and enterprise setup because it starts with an explicit sandbox boundary: + +- non-root sandbox user +- constrained writable paths +- provider-managed credentials +- default-deny network egress +- network policy tied to destination host/port/protocol and binary path + +That boundary is valuable, but it also makes a broad "any agent can do anything" quick start unrealistic. Coding agents have different authentication flows, endpoint sets, child binaries, web access needs, and runtime install behavior. + +The docs should therefore avoid promising that OpenShell is a universal all-agent replacement for Kubernetes on Day 1. + +## Decision + +Keep `docs/openshell.md` intentionally narrow: + +```text +OpenShell sandbox -> OpenAB Discord bot -> Kiro CLI default agent +``` + +The quick start should prove only that: + +1. OpenShell can create the sandbox. +2. OpenShell can inject the Discord bot token through a provider. +3. `openab` can connect to Discord REST and Discord Gateway WebSocket through policy. +4. `kiro-cli` can authenticate and reach its documented service endpoints through policy. +5. A user can mention the Discord bot and get a Kiro-backed reply. + +All other agent backends and broad web/tool access remain Day 2 work. + +The default Day 1 policy should live as a checked-in sample artifact, not as a long inline YAML block in the first-page guide. The quick start applies: + +```text +openshell/samples/kiro-discord-day1-policy.yaml +``` + +Agent/platform combinations should grow under `openshell/samples/` after they have a real E2E pass. For example, Kiro-specific combinations belong in `openshell/samples/kiro.md`; Codex, Claude, Copilot, Gemini, and other coding CLIs should get their own files when maintainers or users contribute tested policies. + +## Why The Quick Start Needs Policy + +OpenShell is default-deny for outbound traffic. A working OpenAB policy must define: + +- the destination host and port +- protocol shape, such as REST or WebSocket +- enforcement mode +- the binary allowed to connect + +For Day 1 this means: + +| Binary | Required purpose | +| --- | --- | +| `/usr/local/bin/openab` | Discord REST API and Discord Gateway WebSocket | +| `/usr/local/bin/kiro-cli*` | Kiro authentication, runtime, management, telemetry, and related AWS service endpoints | + +Use `enforcement: enforce` for the documented happy path. `enforcement: audit` is useful for investigation, but it should not be documented as a substitute for a known-good allowlist. + +## Image Shape + +Do not modify the existing coding CLI images just to make OpenShell work. + +The supported pattern is an OpenShell-specific wrapper image: + +```text +existing OpenAB/Kiro image + -> OpenShell wrapper + -> sandbox user + -> HOME=/sandbox + -> writable /sandbox runtime paths +``` + +This keeps the default Kiro image behavior intact while adapting it to OpenShell's runtime expectations. It also avoids repeating this work across `Dockerfile.codex`, `Dockerfile.claude`, `Dockerfile.gemini`, and other agent-specific images. + +For this Day 1 preset, the wrapper is `openshell/Dockerfile.kiro`. It should not require changes to the existing default Kiro image or the existing native sandbox image. + +## Credential Route + +The quick start should not ask users to paste raw long-lived tokens into `config.toml`. The preferred route is: + +```text +host secret source or local .env + -> host shell environment + -> openshell provider create --credential DISCORD_BOT_TOKEN + -> openshell sandbox create --provider openab-discord + -> /sandbox/config.toml references ${DISCORD_BOT_TOKEN} +``` + +This follows the OpenShell provider model: `openshell provider create --credential API_KEY` can read the value from the host shell environment, store it in the provider, and attach it to a sandbox. The committed OpenAB config should keep only the environment reference. + +## E2E Contract + +A passing E2E run must prove the real OpenShell path: + +- Use real OpenShell. Do not replace the test with native host install, plain `docker run`, Kubernetes, or a host-local OpenAB process. +- Create a real OpenShell sandbox named `oab`. +- Launch `openab run` through `openshell sandbox connect`, `openshell sandbox exec`, or an OpenShell-generated SSH config. +- Do not use raw `docker exec` as the success path. It can be useful for debugging, but it does not prove the same sandbox namespace, proxy, and policy behavior. +- Do not print secrets. Read `DISCORD_BOT_TOKEN` from the host environment or local secret file, then keep command output redacted. +- Stop for human input when Kiro device-flow login requires browser approval. +- Success requires a Discord bot connection and a human mention/reply test in Discord. +- On macOS with Docker Desktop, a successful run must prove that Discord Gateway WebSocket works through the OpenShell-managed route. A Linux-only pass does not prove the macOS path. +- A negative web-access check should ask the agent for a live external fact, such as current weather. The Day 1 preset should not add arbitrary weather/search/browser/package endpoints to make that pass. If the agent can answer only through already-allowed Kiro service traffic, record that separately; it does not prove broad sandbox web access. + +## Known Day 2 Boundary + +The following are intentionally out of scope for the first-page quick start: + +- Codex, Claude, Gemini, AGY, Cursor, Copilot, OpenCode, and other agent-specific OpenShell profiles. +- Arbitrary web browsing. +- GitHub, npm, PyPI, crates.io, Go proxy, cloud SDKs, Docker registries, and third-party APIs. +- Runtime `sudo`, `apt-get install`, or writes to `/usr`, `/opt`, or `/usr/local/bin`. +- Broad wildcard egress policies. +- Automated policy approval flows where the agent asks an external controller to open new endpoints. + +Those use cases can be added later as explicit profiles or policy artifacts after they are tested. + +The documented Day 2 workflow is log-driven: + +1. Watch `openshell logs oab --tail`. +2. Trigger the blocked workflow. +3. Extract the denied host, port, protocol shape, and binary path. +4. Add the narrowest policy entry with `openshell policy update`. +5. Repeat until the relevant denials stop. + +This keeps the sandbox boundary useful while still giving users a clear way to expand egress for their own workflow. + +## Host Support Boundary + +The OpenAB quick start should point users to the OpenShell support matrix before they start. Day 1 should use host/runtime combinations listed by OpenShell, currently Linux Debian/Ubuntu on `amd64` or `arm64`, or macOS Apple Silicon with Docker Desktop. Other combinations are not first-run targets for this guide. + +OpenAB can add notes for combinations we have tested and rejected, but those notes should not turn the Day 1 guide into a platform-debugging document. + +## Future Direction + +OpenAB may eventually need a small OpenShell preset vocabulary: + +| Preset | Purpose | Network posture | +| --- | --- | --- | +| `openab-day1-kiro` | First successful Discord + Kiro setup | Narrow, documented allowlist | +| `openab-dev-agent` | Developer-heavy agent use | Broader web and package ecosystem access | +| `openab-safe-agent` | Enterprise/security-sensitive deployments | Strict per-agent/provider endpoint policy | + +The immediate PR should not solve all three. It should make Day 1 simple, honest, and testable. + +## References + +- [OpenShell policy schema](https://docs.nvidia.com/openshell/reference/policy-schema) +- [OpenShell first network policy tutorial](https://docs.nvidia.com/openshell/get-started/tutorials/first-network-policy) +- [OpenShell support matrix](https://docs.nvidia.com/openshell/reference/support-matrix) +- [OpenShell providers](https://docs.nvidia.com/openshell/sandboxes/manage-providers) +- [Kiro firewall and proxy documentation](https://kiro.dev/docs/cli/privacy-and-security/firewalls/) +- [Kiro remote authentication](https://kiro.dev/docs/cli/authentication/) diff --git a/docs/openshell.md b/docs/openshell.md index 5a0c8449a..09bde44c2 100644 --- a/docs/openshell.md +++ b/docs/openshell.md @@ -1,158 +1,276 @@ -# OpenShell +# OpenShell Quick Start -Run OAB inside an [NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell) sandbox for isolated, policy-enforced execution. +Run one OpenAB Discord bot inside an [NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell) sandbox. -## Architecture +This guide is intentionally narrow. The Day 1 path is: +```text +OpenShell sandbox -> OpenAB Discord bot -> Kiro CLI default agent ``` + +Other coding CLIs can work, but they need their own authentication, network, and tool-install policies. Do not treat this page as a generic Codex/Claude/Gemini/AGY OpenShell guide. + +## Architecture + +```text ┌─────────────────────────────────────────────────────────────────────┐ -│ Host (Linux with Docker) │ +│ Host: Linux server / Zeabur / macOS with Docker Desktop │ │ │ │ ┌───────────────────────────────────────────────────────────────┐ │ -│ │ OpenShell Gateway (systemd user service :17670) │ │ -│ │ • manages sandbox lifecycle │ │ -│ │ • enforces network policy (default-deny egress) │ │ -│ │ • injects provider credentials into sandbox env │ │ +│ │ OpenShell Gateway │ │ +│ │ - creates and manages sandbox lifecycle │ │ +│ │ - injects provider credentials │ │ +│ │ - enforces network policy by binary + host + port + protocol │ │ │ └──────────────────────────┬────────────────────────────────────┘ │ -│ │ creates & policies │ +│ │ creates sandbox "oab" │ │ ▼ │ │ ┌───────────────────────────────────────────────────────────────┐ │ -│ │ Docker Container (sandbox: "oab") │ │ +│ │ OpenShell Sandbox │ │ │ │ │ │ -│ │ /home/sandbox/ │ │ -│ │ └── config.toml ← bot token + agent config │ │ +│ │ /sandbox/ │ │ +│ │ ├── config.toml OpenAB config │ │ +│ │ ├── .local/share/kiro-cli/ Kiro auth/session state │ │ +│ │ ├── .kiro/ Kiro settings/skills │ │ +│ │ ├── bin/ optional user tools │ │ +│ │ └── tmp/ scratch files │ │ │ │ │ │ -│ │ openab run ──stdio JSON-RPC──► openab-agent │ │ +│ │ openab run ──stdio JSON-RPC──► kiro-cli acp --trust-all-tools│ │ │ │ │ │ │ │ -│ │ │ Discord WS │ ChatGPT API │ │ +│ │ │ Discord API/Gateway │ Kiro service endpoints │ │ │ └───────┼──────────────────────────────┼────────────────────────┘ │ -│ │ │ │ -│ ┌────────┼──────────────────────────────┼────────────────────┐ │ -│ │ Network Policy (egress allowlist) │ │ │ -│ │ ✓ discord.com:443 │ │ │ -│ │ ✓ gateway.discord.gg:443 │ │ │ -│ │ ✓ cdn.discordapp.com:443 │ │ │ -│ │ ✓ chatgpt.com:443 ◄────────────────┘ │ │ -│ │ ✓ auth0.openai.com:443 │ │ -│ │ ✗ everything else DENIED │ │ -│ └────────┼───────────────────────────────────────────────────┘ │ -└───────────┼─────────────────────────────────────────────────────────┘ - │ - ▼ -┌──────────────────┐ ┌──────────────────┐ -│ Discord API │ │ ChatGPT API │ -│ (bot gateway) │ │ (chatgpt.com) │ -└──────────────────┘ └──────────────────┘ +│ │ │ │ +│ ┌───────▼──────────────────────────────▼───────────────────────┐ │ +│ │ Day 1 Network Policy │ │ +│ │ - /usr/local/bin/openab -> Discord REST + WebSocket │ │ +│ │ - /usr/local/bin/kiro-cli* -> Kiro auth/runtime endpoints │ │ +│ │ - everything else is denied unless explicitly added │ │ +│ └───────────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────────┘ ``` -## Prerequisites +In OpenShell, `/sandbox` is the writable runtime root for this guide. Keep OpenAB config, Kiro auth state, scratch files, and optional user-installed tools under `/sandbox`. + +## TL;DR -- Docker running on the host (user must be in the `docker` group) -- [OpenShell CLI](https://github.com/NVIDIA/OpenShell#install) installed +From the OpenAB repo root: ```bash -curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh -``` +read -rsp "Discord bot token: " DISCORD_BOT_TOKEN +echo +test -n "$DISCORD_BOT_TOKEN" || { echo "DISCORD_BOT_TOKEN is required"; exit 1; } +export DISCORD_BOT_TOKEN + +openshell sandbox delete oab >/dev/null 2>&1 || true +openshell provider delete openab-discord >/dev/null 2>&1 || true -> **Note:** If the gateway fails with "failed to query Docker daemon version", add your user to the `docker` group and re-login: -> ```bash -> sudo usermod -aG docker $USER -> # Log out and back in (or: loginctl terminate-user $USER) -> ``` +openshell provider create --name openab-discord --type generic --credential DISCORD_BOT_TOKEN -## Quick Start +# Until ghcr.io/openabdev/openab-kiro-sandbox is published, build the wrapper locally. +docker build -t openab-kiro-sandbox -f openshell/Dockerfile.kiro . -### 1. Create credential provider +openshell sandbox create --name oab \ + --provider openab-discord \ + --from openab-kiro-sandbox:latest \ + -- bash + +openshell policy set oab --policy openshell/samples/kiro-discord-day1-policy.yaml --wait +openshell sandbox connect oab +``` + +Then inside the sandbox: ```bash -openshell provider create --name discord --type generic \ - --credential "DISCORD_BOT_TOKEN=your-token-here" +cd /sandbox +test -n "${DISCORD_BOT_TOKEN:-}" || { echo "DISCORD_BOT_TOKEN was not injected"; exit 1; } + +cat > /sandbox/config.toml <<'EOF' +[discord] +bot_token = "${DISCORD_BOT_TOKEN}" +allow_all_channels = true +allow_all_users = true +allow_dm = false +message_processing_mode = "per-thread" + +[agent] +command = "kiro-cli" +args = ["acp", "--trust-all-tools"] +working_dir = "/sandbox" + +[agent.env] +HOME = "/sandbox" +PATH = "/sandbox/bin:/sandbox/.local/bin:/usr/local/bin:/usr/bin:/bin" +TMPDIR = "/sandbox/tmp" + +[pool] +max_sessions = 1 +session_ttl_hours = 1 + +[reactions] +enabled = true +remove_after_reply = false +EOF + +kiro-cli login --use-device-flow +kiro-cli whoami +openab run -c /sandbox/config.toml ``` -### 2. Create sandbox +Mention the bot in Discord. The Day 1 test passes only when the bot replies while `openab run` is running inside the OpenShell sandbox. + +## Supported Day 1 Environments + +Use one of these host paths for this guide: -Using the pre-built image: +| Host path | Day 1 status | Notes | +| --- | --- | --- | +| Linux Debian/Ubuntu `amd64` or `arm64` + Docker Engine | Recommended Day 1 path | Best first path for a remote VM, Zeabur, EC2, home server, or Raspberry Pi. | +| macOS Apple Silicon + Docker Desktop | OpenShell-supported, OpenAB E2E-gated | Docker Desktop provides the Linux runtime substrate. Treat this as valid for OpenAB only after a real Discord reply from inside the OpenShell sandbox. | + +OpenShell's current [support matrix](https://docs.nvidia.com/openshell/reference/support-matrix) lists these supported host platforms and Docker Desktop or Docker Engine as the Docker-backed gateway prerequisite. If a host/runtime combination is not listed there, do not use it as your first Day 1 path. + +## Choose Your Host Path + +OpenAB runs inside a Linux OpenShell sandbox in both paths. + +### Linux Host + +Use this path for a Linux VM or server such as Zeabur, EC2, a home server, or a Raspberry Pi. + +Install Docker with your platform package manager, start it, and verify: ```bash -openshell sandbox create --name oab \ - --from ghcr.io/openabdev/openab-native-sandbox:latest \ - --provider discord \ - -- bash +docker info ``` -Or build locally from `openshell/Dockerfile`: +Install OpenShell with the official installer: ```bash -docker build -t oab-sandbox openshell/ -openshell sandbox create --name oab \ - --from oab-sandbox:latest \ - --provider discord \ - -- bash +curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh ``` -### 3. Set network policy (from host) +Verify: ```bash -openshell policy update oab \ - --add-endpoint "discord.com:443:read-write:rest:enforce" \ - --add-endpoint "gateway.discord.gg:443:read-write:websocket:enforce" \ - --add-endpoint "cdn.discordapp.com:443:read-write:rest:enforce" \ - --add-endpoint "chatgpt.com:443:read-write:rest:enforce" \ - --add-endpoint "auth0.openai.com:443:read-write:rest:enforce" +openshell --version +openshell sandbox list ``` -### 4. Authenticate (inside sandbox) +### macOS Host + +Use this path for a MacBook or Mac mini. Docker Desktop provides the Linux runtime substrate; OpenShell still creates a Linux sandbox. + +Install and start Docker Desktop, then verify: ```bash -sandbox$ openab-agent auth codex-oauth --no-browser +docker info ``` -Open the printed URL in your browser, approve, then paste the `localhost:1455/auth/callback?...` URL back. +Install OpenShell with the official installer: + +```bash +curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh +``` -### 5. Create config and run +Verify: ```bash -sandbox$ cat > config.toml <<'EOF' -[discord] -bot_token = "your-bot-token" -allow_all_channels = true +openshell --version +openshell sandbox list +``` -[agent] -command = "openab-agent" -working_dir = "/home/sandbox" -env = { OPENAB_AGENT_OPENAI_MODEL = "gpt-5.4-mini" } +If Docker Desktop needs macOS approval or first-run setup, finish that in the GUI before continuing. -[pool] -max_sessions = 3 -session_ttl_hours = 1 +## Why Policy Is Required -[reactions] -enabled = true -EOF +OpenShell sandboxes are default-deny for outbound network traffic. A working policy must name: + +- the destination host and port +- the protocol shape, such as REST or WebSocket +- the exact binary allowed to connect + +For OpenAB Day 1, this means `openab` needs Discord REST and Discord Gateway WebSocket access, while `kiro-cli` needs the Kiro service endpoints listed by Kiro's firewall documentation. + +The sample policy uses `enforcement: enforce`. Do not use `enforcement: audit` as a shortcut for this quick start: audit is useful for investigation, but it is not a replacement for a known-good Day 1 allowlist. -sandbox$ openab run --config config.toml +## Day 2: Add Egress Deliberately + +After the bot can reply in Discord, keep OpenShell policy narrow and add only the egress your workflow actually needs. + +Watch the OpenShell logs in another terminal: + +```bash +openshell logs oab --tail ``` -## Network Policy +Or inspect the last few minutes after a failed request: + +```bash +openshell logs oab --since 5m +``` -OpenShell sandboxes have **default-deny egress**. Required endpoints by backend: +When an outbound request is blocked, identify three fields from the log: -| Backend | Endpoints | -|---------|-----------| -| All | `discord.com:443`, `gateway.discord.gg:443`, `cdn.discordapp.com:443` | -| Native Agent (codex) | `chatgpt.com:443`, `auth0.openai.com:443` | -| Native Agent (anthropic) | `api.anthropic.com:443` | -| GitHub access | `api.github.com:443`, `github.com:443` | +- blocked host and port +- binary path +- protocol shape, such as REST or WebSocket -## Reconnecting +Then add the minimum endpoint for that binary: ```bash -openshell sandbox connect oab +openshell policy update oab \ + --add-endpoint api.example.com:443:read-only:rest:enforce \ + --binary /usr/local/bin/kiro-cli ``` +Repeat until the logs stop showing relevant denials for the workflow you are testing. Do not add broad package registries, cloud APIs, search APIs, or arbitrary web access to the Day 1 policy unless that access is part of a tested sample. + +For Kiro with other chat platforms, start with [OpenShell Kiro samples](../openshell/samples/kiro.md). Missing combinations are expected to be contributed after a real E2E pass. + +## E2E Rules + +For a test run to count: + +- Launch `openab run` through OpenShell: `openshell sandbox connect`, `openshell sandbox exec`, or an OpenShell-generated SSH config. +- Do not use raw `docker exec` as proof. It can enter the OpenShell-created container without proving the same sandbox namespace, proxy, and policy path. +- Do not edit the coding CLI images to make this work. The OpenShell Kiro sandbox is a wrapper around the existing default Kiro image. +- Do not broaden this guide to arbitrary web, GitHub, npm, PyPI, cloud SDKs, or other agents. Those are Day 2 policy work. +- On macOS with Docker Desktop, the proof is the actual Discord bot connection and reply. If the Discord WebSocket cannot connect through the OpenShell-managed route, the guide is not yet valid for that host path. + +For deeper policy, access, usability, and E2E notes, read [ADR: OpenShell OpenAB Preset Module](adr/openshell-openab-preset-module.md). + +## OpenShell Or Kubernetes? + +| Choose | When | +| --- | --- | +| OpenShell | You want a single-machine sandbox that can get the default OpenAB + Discord + Kiro path running quickly, with explicit egress policy. | +| Kubernetes | You already operate Kubernetes, need mature production rollout controls, or expect many agents, services, secrets, and network policies. | + +## Troubleshooting + +| Symptom | Meaning | Next step | +| --- | --- | --- | +| `docker info` fails | Docker is not ready | Start Docker Desktop or Docker Engine | +| `openshell sandbox list` fails | OpenShell gateway/driver is not ready | Fix OpenShell before continuing | +| `DISCORD_BOT_TOKEN was not injected` | Provider was not attached or token env was empty | Recreate the provider and sandbox | +| Discord connects on Linux but not macOS | macOS/Docker route may require proxy-aware WebSocket behavior | Treat as an OpenShell/macOS E2E blocker, not a successful run | +| Kiro login cannot reach auth/runtime endpoints | Kiro endpoint policy is incomplete | Check `openshell logs oab --since 10m` for denied host and binary | +| Agent tries to install into `/usr` | Runtime sandbox is non-root | Install only under `/sandbox` | + ## Cleanup ```bash openshell sandbox delete oab -openshell provider delete discord +openshell provider delete openab-discord ``` + +## Related Docs + +- [Discord setup](discord.md) +- [Kiro CLI](kiro.md) +- [Agent-installable tools](agent-installable-tools.md) +- [OpenShell Kiro samples](../openshell/samples/kiro.md) +- [OpenShell policy ADR](adr/openshell-openab-preset-module.md) +- [OpenShell support matrix](https://docs.nvidia.com/openshell/reference/support-matrix) +- [OpenShell policy schema](https://docs.nvidia.com/openshell/reference/policy-schema) +- [OpenShell first network policy tutorial](https://docs.nvidia.com/openshell/get-started/tutorials/first-network-policy) +- [Kiro firewall documentation](https://kiro.dev/docs/cli/privacy-and-security/firewalls/) diff --git a/openshell/Dockerfile.kiro b/openshell/Dockerfile.kiro new file mode 100644 index 000000000..77e337bb9 --- /dev/null +++ b/openshell/Dockerfile.kiro @@ -0,0 +1,21 @@ +FROM ghcr.io/openabdev/openab:beta + +USER root +RUN apt-get update && apt-get install -y --no-install-recommends iproute2 && rm -rf /var/lib/apt/lists/* +RUN groupadd -g 1000660000 sandbox && \ + useradd -u 1000660000 -g sandbox -m -d /sandbox -s /bin/bash sandbox && \ + mkdir -p \ + /sandbox/bin \ + /sandbox/.local/bin \ + /sandbox/.cache \ + /sandbox/.local/share/kiro-cli \ + /sandbox/.kiro \ + /sandbox/tmp \ + /sandbox/work && \ + chown -R sandbox:sandbox /sandbox + +USER sandbox +ENV HOME=/sandbox +ENV PATH=/sandbox/bin:/sandbox/.local/bin:/usr/local/bin:/usr/bin:/bin +ENV TMPDIR=/sandbox/tmp +WORKDIR /sandbox diff --git a/openshell/samples/kiro-discord-day1-policy.yaml b/openshell/samples/kiro-discord-day1-policy.yaml new file mode 100644 index 000000000..05763a5e7 --- /dev/null +++ b/openshell/samples/kiro-discord-day1-policy.yaml @@ -0,0 +1,73 @@ +version: 1 +filesystem_policy: + include_workdir: true + read_only: + - /usr + - /lib + - /lib64 + - /bin + - /sbin + - /etc + - /app + - /var/log + - /proc + - /dev/urandom + read_write: + - /sandbox + - /tmp + - /dev/null +landlock: + compatibility: best_effort +process: + run_as_user: sandbox + run_as_group: sandbox +network_policies: + discord: + name: openab-discord + endpoints: + - host: discord.com + port: 443 + protocol: rest + enforcement: enforce + access: full + - host: gateway.discord.gg + port: 443 + protocol: websocket + enforcement: enforce + access: full + - host: cdn.discordapp.com + port: 443 + protocol: rest + enforcement: enforce + access: read-only + - host: media.discordapp.net + port: 443 + protocol: rest + enforcement: enforce + access: read-only + binaries: + - { path: /usr/local/bin/openab } + kiro: + name: kiro-cli + endpoints: + - { host: app.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: assets.app.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: read-only } + - { host: cli.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: prod.us-east-1.auth.desktop.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: prod.us-east-1.telemetry.desktop.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: prod.download.desktop.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: read-only } + - { host: prod.download.cli.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: read-only } + - { host: desktop-release.q.us-east-1.amazonaws.com, port: 443, protocol: rest, enforcement: enforce, access: read-only } + - { host: q.us-east-1.amazonaws.com, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: q.eu-central-1.amazonaws.com, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: runtime.us-east-1.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: runtime.eu-central-1.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: management.us-east-1.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: management.eu-central-1.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: telemetry.us-east-1.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: telemetry.eu-central-1.kiro.dev, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: cognito-identity.us-east-1.amazonaws.com, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: oidc.us-east-1.amazonaws.com, port: 443, protocol: rest, enforcement: enforce, access: full } + - { host: client-telemetry.us-east-1.amazonaws.com, port: 443, protocol: rest, enforcement: enforce, access: full } + binaries: + - { path: /usr/local/bin/kiro-cli* } diff --git a/openshell/samples/kiro.md b/openshell/samples/kiro.md new file mode 100644 index 000000000..bb553b00e --- /dev/null +++ b/openshell/samples/kiro.md @@ -0,0 +1,28 @@ +# OpenShell Kiro Samples + +This file collects OpenShell policy notes for Kiro-backed OpenAB setups. + +## Discord Day 1 + +Use [`kiro-discord-day1-policy.yaml`](kiro-discord-day1-policy.yaml) with the main [OpenShell quick start](../../docs/openshell.md). + +This is the default Day 1 combination: + +```text +OpenShell sandbox -> OpenAB Discord bot -> Kiro CLI +``` + +The policy permits: + +- `/usr/local/bin/openab` to reach Discord REST and Gateway WebSocket endpoints. +- `/usr/local/bin/kiro-cli*` to reach Kiro auth, runtime, management, telemetry, download, and related AWS service endpoints. + +## Other Chat Platforms + +Telegram, LINE, Slack, Teams, WeCom, and other adapters should be added here only after an end-to-end OpenShell test proves: + +- the bot process can connect to the platform API and any required WebSocket or webhook endpoint +- Kiro can authenticate and reply through OpenAB +- blocked egress logs are resolved by the documented policy + +Until a platform section exists here, treat it as a Day 2 policy task rather than a guaranteed Day 1 path.