From cd26906105267bfd21014dc916038a119dd4dfce Mon Sep 17 00:00:00 2001 From: kawaiipunk Date: Wed, 12 Aug 2026 18:26:06 +0100 Subject: [PATCH] =?UTF-8?q?Initial=20opencode=E2=80=91tinfoil=20nono=20pro?= =?UTF-8?q?file=20repository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/validate.yml | 21 +++++ LICENSE | 21 +++++ Makefile | 19 ++++ README.md | 66 ++++++++++++++ bin/opencode | 4 + profiles/opencode-tinfoil.jsonc | 148 ++++++++++++++++++++++++++++++++ scripts/install.sh | 41 +++++++++ 7 files changed, 320 insertions(+) create mode 100644 .github/workflows/validate.yml create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100755 bin/opencode create mode 100644 profiles/opencode-tinfoil.jsonc create mode 100755 scripts/install.sh diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..71f7939 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,21 @@ +name: validate + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install nono + run: | + brew tap guybedford/nono + brew install nono + + - name: Validate profile + run: nono profile validate opencode-tinfoil \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fe8deaf --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 YOUR_NAME + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0646103 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +PREFIX ?= $(HOME)/.local +PROFILE_DIR = $(HOME)/.config/nono/profiles +BIN_DIR = $(PREFIX)/bin + +.PHONY: install uninstall validate test + +install: + @./scripts/install.sh + +uninstall: + rm -f $(PROFILE_DIR)/opencode-tinfoil.json + rm -f $(BIN_DIR)/opencode + @echo "Uninstalled." + +validate: + nono profile validate opencode-tinfoil + +test: + nono run --profile opencode-tinfoil --allow-cwd -- opencode --version \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..bb534fb --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +# nono-opencode-tinfoil + +A [`nono`](https://github.com/guybedford/nono) sandbox profile for running +[OpenCode](https://opencode.ai) with access to [Tinfoil](https://tinfoil.sh) +enclaves and other LLM providers. + +## Install + +### macOS / Linux + +```bash +git clone https://github.com/YOUR_USERNAME/nono-opencode-tinfoil.git +cd nono-opencode-tinfoil +make install +``` + +This installs the profile to `~/.config/nono/profiles/` and a wrapper script +to `~/.local/bin/`. + +### Requirements + +- [nono](https://github.com/guybedford/nono) installed +- `opencode` installed globally (e.g. `npm i -g opencode-ai`) + +## Usage + +After install, run OpenCode from any project directory: + +```bash +opencode +``` + +Or use the profile directly: + +```bash +nono run --profile opencode-tinfoil --allow-cwd -- opencode +``` + +## Tinfoil integration + +The profile allows network access to: + +- `*.tinfoil.sh` +- `inference.tinfoil.sh` +- `containers.tinfoil.sh` +- `ghcr.io` + +and grants read/write access to `~/.tinfoil` for Tinfoil credentials. + +## Security model + +- Current working directory: read/write +- OpenCode config: read/write +- Tinfoil config: read/write +- SSH private keys, AWS/GCP/Azure credentials, kubeconfig: denied +- `sudo`, `su`, `doas`, `passwd`, disk tools: denied + +## Uninstall + +```bash +make uninstall +``` + +## License + +MIT \ No newline at end of file diff --git a/bin/opencode b/bin/opencode new file mode 100755 index 0000000..7fe3d4d --- /dev/null +++ b/bin/opencode @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -euo pipefail + +exec nono run --profile opencode-tinfoil --allow-cwd -- opencode "$@" \ No newline at end of file diff --git a/profiles/opencode-tinfoil.jsonc b/profiles/opencode-tinfoil.jsonc new file mode 100644 index 0000000..c80c1f6 --- /dev/null +++ b/profiles/opencode-tinfoil.jsonc @@ -0,0 +1,148 @@ +{ + "meta": { + "name": "opencode-tinfoil", + "description": "OpenCode sandbox with Tinfoil enclave and LLM API access" + }, + "groups": { + "include": ["deny_credentials"] + }, + "commands": { + "allow": [ + "git", + "node", + "npm", + "npx", + "bun", + "python3", + "python", + "pip", + "pip3", + "cargo", + "rustc", + "go", + "tinfoil" + ], + "deny": [ + "sudo", + "su", + "doas", + "pkexec", + "passwd", + "chsh", + "usermod", + "useradd", + "deluser", + "rm -rf /", + "mkfs", + "dd", + "fdisk", + "parted" + ] + }, + "workdir": { + "access": "readwrite" + }, + "filesystem": { + "allow": [ + "." + ], + "read": [ + "${HOME}/.config/opencode", + "${HOME}/.local/share/opencode", + "${HOME}/.opencode", + "${HOME}/.claude", + "${HOME}/.gitconfig", + "${HOME}/.ssh/config", + "${HOME}/.tinfoil", + "/etc/ssl", + "/etc/pki", + "/usr/share/ca-certificates", + "/usr/local/share/ca-certificates", + "/tmp" + ], + "write": [ + "${HOME}/.config/opencode", + "${HOME}/.local/share/opencode", + "${HOME}/.opencode", + "${HOME}/.claude", + "/tmp" + ], + "deny": [ + "${HOME}/.ssh/id_*", + "${HOME}/.gnupg", + "${HOME}/.aws", + "${HOME}/.azure", + "${HOME}/.gcp", + "${HOME}/.kube", + "${HOME}/.docker/config.json", + "${HOME}/.netrc", + "${HOME}/.npmrc", + "/etc/shadow", + "/etc/passwd", + "/etc/hosts" + ] + }, + "network": { + "block": false, + "allow_domain": [ + "api.openai.com", + "api.anthropic.com", + "api.groq.com", + "api.together.xyz", + "api.openrouter.com", + "generativelanguage.googleapis.com", + "api.mistral.ai", + "api.cohere.com", + "api.x.ai", + "api.deepseek.com", + "api.perplexity.ai", + "api.gemini.google.com", + "api.fireworks.ai", + "api.replicate.com", + "api.ollama.local", + "llm.api.cloudflare.com", + "api.scaleway.ai", + "api.alibabacloud.com", + "api.moonshot.cn", + "api.minimaxi.com", + "api.stepfun.com", + "api.01.ai", + "inference.tinfoil.sh", + "*.tinfoil.sh", + "api.tinfoil.sh", + "containers.tinfoil.sh", + "ghcr.io", + "registry.npmjs.org", + "npmjs.org", + "github.com", + "raw.githubusercontent.com", + "objects.githubusercontent.com", + "huggingface.co", + "cdn.jsdelivr.net", + "unpkg.com", + "esm.sh", + "deno.land", + "crates.io", + "index.crates.io", + "static.crates.io", + "proxy.golang.org", + "sum.golang.org", + "pypi.org", + "files.pythonhosted.org", + "download.pytorch.org" + ] + }, + "environment": { + "set_vars": { + "OPENCODE_CONFIG_DIR": "${HOME}/.config/opencode", + "TINFOIL_CONFIG_DIR": "${HOME}/.tinfoil" + }, + "deny_vars": [ + "AWS_SECRET_ACCESS_KEY", + "AWS_ACCESS_KEY_ID", + "AZURE_CLIENT_SECRET", + "GCP_PRIVATE_KEY", + "KUBECONFIG" + ] + } +} \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..de00db2 --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +PROFILE_NAME="opencode-tinfoil" +PROFILE_SRC="profiles/${PROFILE_NAME}.jsonc" +PROFILE_DIR="${HOME}/.config/nono/profiles" +BIN_DIR="${HOME}/.local/bin" +WRAPPER_SRC="bin/opencode" + +if ! command -v nono &>/dev/null; then + echo "Error: nono is not installed. Install it first:" + echo " brew install nono" + exit 1 +fi + +if [[ ! -f "${PROFILE_SRC}" ]]; then + echo "Error: profile not found at ${PROFILE_SRC}" + exit 1 +fi + +mkdir -p "${PROFILE_DIR}" +mkdir -p "${BIN_DIR}" + +cp "${PROFILE_SRC}" "${PROFILE_DIR}/${PROFILE_NAME}.json" +chmod 644 "${PROFILE_DIR}/${PROFILE_NAME}.json" + +cp "${WRAPPER_SRC}" "${BIN_DIR}/opencode" +chmod 755 "${BIN_DIR}/opencode" + +nono profile validate "${PROFILE_NAME}" + +echo "Installed:" +echo " Profile: ${PROFILE_DIR}/${PROFILE_NAME}.json" +echo " Wrapper: ${BIN_DIR}/opencode" + +if [[ ":${PATH}:" != *":${BIN_DIR}:"* ]]; then + echo "" + echo "Warning: ${BIN_DIR} is not in your PATH." + echo "Add this to your shell profile:" + echo " export PATH=\"${BIN_DIR}:\${PATH}\"" +fi \ No newline at end of file