Repository navigation
Conversation
`nbox serve --http --netbox-token-passthrough` (or `[serve].netbox_token_passthrough = true`) lets one process serve many users: each caller presents their own NetBox API token per request and nbox forwards it verbatim, so NetBox's object permissions and changelog apply to the real caller — no IdP and no `[serve.vault]` mapping. The token is read from `X-NetBox-Token`, or from `Authorization` when that header isn't already used by OIDC or `--http-token` (so a host that can only set a bearer works, without ever mistaking a JWT for a NetBox token). Each request builds its own client from the caller's credential. Isolation is a correctness requirement here, not an optimization, since NetBox returns different results to different users: - the read cache is partitioned per token fingerprint; - `nbox_cache_clear` drops only the caller's own partition; - `--allow-writes` runs writes under the caller's token. Fail closed: a request without a caller token is rejected with 401 and never downgraded to the server's profile token. Tokens are redacted in Debug, logs, and errors; the audit log carries `auth=netbox-token` plus a short SHA-256 fingerprint, which also keys the per-caller rate limit. Pass-through requires the HTTP transport — stdio has no per-request headers, so asking for it there is a usage error rather than a silent no-op — and it allows a routable bind, with TLS terminated in front. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ADR-0001 §7 documents MCP writes as running "in one of two explicit modes"; pass-through adds a third credential path, so the decision needs a record of the same rank. Follows the ADR-0002 precedent: what problem the mode solves (no per-user RBAC without an IdP and vault), the decision (caller NetBox API token forwarded verbatim, fail closed, cache partitioned per fingerprint), and the accepted trade-offs (TLS required in front, IP-keyed pre-auth rate limit, tokens in process memory). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`Dockerfile.release` only wraps a prebuilt binary from the release matrix, so there was no way to build and run the server from a checkout. Add a multi-stage `Dockerfile` plus a `docker-compose.yml` aimed at the multi-user pass-through mode, where running a shared container is the point. The runtime image is unprivileged (uid 10001), read-only, drops all capabilities, and carries nothing but the binary and CA certificates. It publishes on loopback so a TLS-terminating proxy fronts it — callers send real NetBox credentials on every request, so plaintext off-host would leak them. No NetBox token is baked into the image or the shipped config: in pass-through mode the container has no shared credential, which is the security property worth preserving in the packaging too. The config is file-backed rather than inline because a `read_only` service cannot take content-based compose configs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Compose previously hard-coded 127.0.0.1:8080 and offered no way to give the
container extra trust anchors. Set NBOX_BIND/NBOX_PORT to publish elsewhere
(loopback stays the default — callers send real NetBox credentials on every
request, so anything wider should be fronted by a TLS-terminating proxy), and
mount ${NBOX_CA_BUNDLE} at /etc/nbox/ca.pem for a NetBox behind an internal
CA, harmless when unset.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
Dockerfile.releaseonly wraps a prebuilt binary from the release matrix, so there is no way to build and run the server from a checkout — and the multi-user pass-through mode (see #151) is exactly the deployment where a container is the natural shape: one shared process, TLS terminated in front.Change
A multi-stage
Dockerfile(build from source with--locked, runtime ondebian:bookworm-slim) and adocker-compose.ymlaimed at the pass-through mode.Security posture of the runtime image:
USER 10001, no shell)no-new-privilegesNBOX_BIND/NBOX_PORTonly behind a TLS-terminating proxyNBOX_CA_BUNDLEmount (/etc/nbox/ca.pem,:ro) for a NetBox behind an internal CA — harmless when unsetexamples/nbox-docker.tomlis deliberately token-free: in pass-through mode the caller's token is the only credential, and a missing one must fail rather than fall back to a server-side identity.Notes for review
Stacked on #151 — merge after it; until then the diff also shows the pass-through changes. If you'd rather keep only
Dockerfile.release, happy to drop this — the compose file is the part with real value.Checks
No Rust-code changes: fmt/clippy/build/test green as on the base branch (1404 passed / 0 failed). Docker build verified locally (
docker compose build+ config smoke).