* feat(sbom): add SBOM generation, license resolution, and CSV export tooling
Add mise-integrated SBOM pipeline for container images using Syft.
Includes license resolution via crates.io/npm/PyPI APIs and CycloneDX
JSON to CSV conversion. Adds agent skill for on-demand SBOM operations.
Closes#237
* fix(sbom): chain task dependencies to run generate → resolve → csv sequentially
* fix(sbom): add concurrent license resolution, progress logging, and exclude dev artifacts
* feat(notices): add mise run notices to generate THIRD-PARTY-NOTICES with full license texts
Use cargo-about for Rust crate licenses and pip-licenses for Python
packages. Produces a single attribution file with per-package copyright
notices and full license text for open-source compliance.
Closes#48, #52
## Summary
- Replace the envoy-gateway-based TLS setup with inline PKI generation during cluster bootstrap, generating CA, server, and client certificates directly in the `navigator-bootstrap` crate
- Remove all envoy gateway Helm templates (`gateway.yaml`, `gatewayclass.yaml`, `grpcroute.yaml`, PKI job, traffic policies) and the `Dockerfile.pki-job`
- Add native mTLS support to the navigator server with `tokio-rustls`, mounting client TLS certs as volumes into sandbox pods
- Update cluster entrypoint, healthcheck, and deploy scripts to work with the new direct-TLS architecture
- Add TLS security e2e test and fix formatting/clippy warnings
## Test Plan
- All unit tests pass (`cargo test --workspace`)
- Clippy clean (`cargo clippy --workspace --all-targets`)
- Format clean (`cargo fmt --all -- --check`)
- Python tests pass (`uv run pytest python/`)
- Full `mise run pre-commit` passes
## What changed
- Added tag-driven release flow in GitLab CI:
- new `release` stage with tag-only jobs
- `publish_tag_artifacts` publishes Docker + Python artifacts on `vX.Y.Z` tags
- `create_release_notes` generates release notes from conventional commits via `git-cliff` and creates a GitLab release via `glab`
- Updated main-branch image publishing to version-aware tagging:
- `publish_ecr_images` now runs `mise run publish:main`
- main publishes `:dev`, `:latest`, and a versioned dev tag
- Added release-oriented mise tasks:
- `publish:main`
- `publish:tag`
- `python:publish:macos` (manual macOS arm64 wheel publish)
- Switched Linux Python wheel builds to buildx:
- added `deploy/docker/Dockerfile.python-wheels`
- replaced old per-arch docker-run tasks with `python:build:multiarch`
- Added macOS arm64 wheel build path for local publishing:
- `python:build:macos` builds `aarch64-apple-darwin`
- intended to run locally on macOS after tag CI finishes
- Made Docker multiarch publish script tag-flexible:
- `TAG_LATEST` is no longer hardcoded in ECR mode
- supports `EXTRA_DOCKER_TAGS`
- applies extra tags to sandbox/server/pki-job/cluster images
- Moved release tooling to `build/scripts/release.py` and updated all mise references
- Removed obsolete Docker Artifactory env vars from `mise.toml`
## Release behavior
- **Main branch CI**
- Docker: `:dev`, `:latest`, and versioned dev tag
- **Tag CI (`vX.Y.Z`)**
- Docker: `:X.Y.Z` only (no `:latest`)
- Python: Linux wheels published from CI
- GitLab release notes created from conventional commits
- **Manual macOS step (after tagging)**
1. Checkout the tag locally on macOS
2. Run `mise run python:publish:macos`
## Validation
- `mise run python:lint`
- `mise run version:print`
- `mise run python:build:macos`
- `uv run python build/scripts/release.py --help`
In proxy mode, processes could bypass HTTP_PROXY env vars and connect
directly to any IP since seccomp cannot filter connect() by destination.
This adds network namespace isolation:
- Create isolated netns with veth pair (10.200.0.1 <-> 10.200.0.2)
- Proxy binds to host side of veth
- Sandboxed process enters netns via setns() in pre_exec
- Only network path out is through the proxy
Also adds CAP_SYS_ADMIN and CAP_NET_ADMIN to container configs and
installs iproute2 for namespace management.