Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/onboarding_issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ body:
id: install-method
attributes:
label: How did you install nono?
placeholder: "e.g. Homebrew tap, cargo install, downloaded binary from GitHub releases..."
placeholder: "e.g. Homebrew, cargo install, downloaded binary from GitHub releases..."
validations:
required: true

Expand Down
62 changes: 62 additions & 0 deletions .github/workflows/nix-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: NixOS Integration Tests

on:
pull_request:
branches: [main]
push:
branches: [main]

permissions:
contents: read

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -Dwarnings

jobs:
nix-integration:
name: Nix Integration Tests
if: ${{ !startsWith(github.head_ref, 'dependabot/github_actions/') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libdbus-1-dev pkg-config

- name: Install Nix
uses: cachix/install-nix-action@2126ae7fc54c9df00dd18f7f18754393182c73cd # v31

- name: Pin nixpkgs channel
run: |
nix-channel --remove nixpkgs || true
nix-channel --add https://nixos.org/channels/nixos-24.11 nixpkgs
nix-channel --update nixpkgs

- name: Install Nix test packages
run: |
nix-env -iA nixpkgs.coreutils
nix-env -iA nixpkgs.bash
nix-env -iA nixpkgs.python3
nix-env -iA nixpkgs.nodejs
nix-env -iA nixpkgs.curl

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable

- name: Cache cargo registry
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: nix-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
nix-cargo-

- name: Build release binary
run: cargo build --release

- name: Run Nix integration tests
run: ./tests/run_nix_integration_tests.sh
51 changes: 9 additions & 42 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,50 +156,17 @@ jobs:
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

update-homebrew:
name: Update Homebrew Formula
update-homebrew-core:
name: Bump Homebrew Core Formula
needs: release
runs-on: ubuntu-latest
# Only update stable formula for non-prerelease versions
if: ${{ !contains(github.ref_name, 'alpha') && !contains(github.ref_name, 'beta') && !contains(github.ref_name, 'rc') }}
steps:
- name: Checkout homebrew-nono
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Bump homebrew-core formula
uses: mislav/bump-homebrew-formula-action@56a283fa15557e9abaa4bdb63b8212abc68e655c # v3.6
with:
repository: always-further/homebrew-nono
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
path: homebrew-nono

- name: Download macOS artifacts
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
pattern: nono-*-apple-darwin
path: artifacts

- name: Update formula
run: |
VERSION="${{ env.RELEASE_TAG }}"
VERSION="${VERSION#v}"

# Calculate SHA256 for both architectures
ARM64_SHA=$(sha256sum artifacts/nono-aarch64-apple-darwin/nono-*-aarch64-apple-darwin.tar.gz | cut -d' ' -f1)
X64_SHA=$(sha256sum artifacts/nono-x86_64-apple-darwin/nono-*-x86_64-apple-darwin.tar.gz | cut -d' ' -f1)

# Update formula version and checksums
cd homebrew-nono
sed -i "s/version \".*\"/version \"${VERSION}\"/" Formula/nono.rb
# Update URLs (both directory path and filename)
sed -i "s|releases/download/v[^/]*/nono-v[^-]*-|releases/download/v${VERSION}/nono-v${VERSION}-|g" Formula/nono.rb
# Update ARM64 SHA (first sha256 in on_arm block)
sed -i "/on_arm/,/end/{s/sha256 \"[^\"]*\"/sha256 \"${ARM64_SHA}\"/}" Formula/nono.rb
# Update x64 SHA (sha256 in on_intel block)
sed -i "/on_intel/,/end/{s/sha256 \"[^\"]*\"/sha256 \"${X64_SHA}\"/}" Formula/nono.rb

- name: Commit and push
run: |
cd homebrew-nono
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/nono.rb
git diff --staged --quiet || git commit -m "Update nono to ${{ env.RELEASE_TAG }}"
git push
formula-name: nono
tag-name: ${{ env.RELEASE_TAG }}
download-url: "https://github.com/always-further/nono/archive/refs/tags/${{ env.RELEASE_TAG }}.tar.gz"
env:
COMMITTER_TOKEN: ${{ secrets.HOMEBREW_CORE_TOKEN }}
35 changes: 5 additions & 30 deletions .github/workflows/sign-instruction-files.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Sign instruction files with Sigstore keyless attestation.
# Sign instruction files with the official nono-attest GitHub Action.
#
# Produces .bundle sidecar files containing DSSE envelopes with in-toto
# Produces Sigstore bundles containing DSSE envelopes with in-toto
# statements that nono's trust pipeline can verify. Uses GitHub Actions
# OIDC for identity Fulcio issues a short-lived certificate carrying
# OIDC for identity; Fulcio issues a short-lived certificate carrying
# the repository, workflow, and ref claims.
#
# Consumer-side verification: nono's pre-exec trust scan validates bundles
Expand All @@ -22,37 +22,12 @@ on:

permissions:
id-token: write # Sigstore keyless OIDC token
contents: write # Commit .bundle sidecars
contents: write # Commit generated bundle files

jobs:
sign:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Install nono
run: |
LATEST_TAG=$(gh release view --repo always-further/nono --json tagName -q .tagName)
curl -fsSL "https://github.com/always-further/nono/releases/download/${LATEST_TAG}/nono-${LATEST_TAG}-x86_64-unknown-linux-gnu.tar.gz" | tar xz
sudo mv nono /usr/local/bin/
env:
GH_TOKEN: ${{ github.token }}

- name: Sign instruction files
run: nono trust sign --keyless --all

- name: Commit bundles
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

git add -A '*.bundle'

if git diff --cached --quiet; then
echo "No bundle changes to commit."
exit 0
fi

git commit -m "chore: update instruction file attestation bundles [skip ci]"
git push
- uses: always-further/nono-attest@6b5bd8fbf7e1946e8711338eff11646ecdff87d3 # v0.0.3
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ nono audit show 20260216-193311-20751 --json
### macOS

```bash
brew tap always-further/nono
brew install nono
```

Expand Down
1 change: 0 additions & 1 deletion crates/nono-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ CLI for capability-based sandboxing using Landlock (Linux) and Seatbelt (macOS).
### Homebrew (macOS)

```bash
brew tap always-further/nono
brew install nono
```

Expand Down
8 changes: 5 additions & 3 deletions crates/nono-cli/data/policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,6 @@
"/dev/zero",
"/dev/full",
"/dev/tty",
"/dev/pts",
"$TMPDIR"
]
}
Expand Down Expand Up @@ -364,7 +363,9 @@
"~/.npm",
"~/.node",
"~/.local/share/fnm",
"/usr/local/lib/node_modules"
"/usr/local/lib/node_modules",
"~/Library/pnpm",
"~/.local/share/pnpm"
]
}
},
Expand All @@ -378,11 +379,12 @@
}
},
"python_runtime": {
"description": "Python runtime paths",
"description": "Python runtime paths (pyenv, conda, uv)",
"allow": {
"read": [
"~/.pyenv",
"~/.local/lib",
"~/.local/share/uv",
"~/.conda"
]
}
Expand Down
1 change: 1 addition & 0 deletions crates/nono-cli/src/capability_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ mod tests {
proxy_allow: vec![],
proxy_credential: vec![],
external_proxy: None,
external_proxy_bypass: vec![],
override_deny: vec![],
allow_command: vec![],
block_command: vec![],
Expand Down
15 changes: 14 additions & 1 deletion crates/nono-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ pub struct SandboxArgs {
"proxy_allow",
"proxy_credential",
"external_proxy",
"external_proxy_bypass",
"proxy_port"
]
)]
Expand Down Expand Up @@ -318,9 +319,20 @@ pub struct SandboxArgs {

/// Chain through an external (enterprise) proxy.
/// Format: host:port (e.g., squid.corp.internal:3128)
#[arg(long, value_name = "HOST:PORT")]
#[arg(long, value_name = "HOST:PORT", env = "NONO_EXTERNAL_PROXY")]
pub external_proxy: Option<String>,

/// Domains to route directly instead of through the external proxy.
/// Supports exact hostnames and wildcards (e.g., *.internal.corp).
/// Can be specified multiple times. Requires --external-proxy (or profile equivalent).
#[arg(
long,
value_name = "HOST",
env = "NONO_EXTERNAL_PROXY_BYPASS",
value_delimiter = ','
)]
pub external_proxy_bypass: Vec<String>,

/// Fixed port for the credential injection proxy (default: OS-assigned).
/// Use this when the sandboxed application requires a known proxy port
/// (e.g., for base URL configuration that can't read environment variables).
Expand Down Expand Up @@ -403,6 +415,7 @@ impl SandboxArgs {
self.network_profile.is_some()
|| !self.proxy_allow.is_empty()
|| !self.proxy_credential.is_empty()
|| self.external_proxy.is_some()
}
}

Expand Down
Loading
Loading