confine

package
v0.44.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package confine implements per-request root confinement for the /api/files surface. It lets a host app (e.g. work.example.com proxying the embedded filex explorer) lock a caller into a single sub-folder so a multi-tenant deploy can never let one project read or mutate another's files.

The confinement root comes from two trusted sources, combined narrowest-wins:

  1. An API token's `root:<adapter>://<rel>` scope — the HARD ceiling. The browser never holds the token (the host injects it server-side), so a token-confined caller cannot escape its root.
  2. The `X-Filex-Root: <adapter>://<rel>` request header — narrows further within the token root (or, absent a token root, sets the root). Set by the host's trusted proxy per request; a stray client header can only narrow, never widen past the token root.

Enforcement is a single chi middleware that rewrites/validates every path-bearing field of the request (query `?path=` and the JSON body `path`/`item`/`target`/`sourceDir`/`source[]`/`items[].path`). Anything outside the root is rejected 403; a root/empty path is rewritten to the confined folder so listings open there. Because it sits in one place it cannot miss an endpoint.

Index

Constants

This section is empty.

Variables

View Source
var ErrOutOfRoot = errors.New("path outside confined root")

ErrOutOfRoot is returned when a requested path escapes the confinement root.

Functions

func Middleware

func Middleware(next http.Handler) http.Handler

Middleware enforces the effective root on every /api/files request. Mount it AFTER the auth middleware so the token is on the context.

Types

type Root

type Root struct {
	Adapter string
	Rel     string
}

Root is a confinement scope: a single storage adapter + a clean relative prefix within it (no leading/trailing slash; "" == the storage root).

func FromRequest

func FromRequest(r *http.Request) (Root, bool, error)

FromRequest derives the effective confinement root for r: the token's `root:` scope narrowed by an X-Filex-Root header. Returns ok=false when the request is unrestricted (no token root and no header) — admins / the native panel keep full access.

func ParseRoot

func ParseRoot(raw string) (Root, bool)

ParseRoot exposes parseRoot to the protocol servers, which read a confinement out of an API token's `root:` scope themselves — they authenticate outside the HTTP chain, so the middleware in this package never runs for them. Returns ok=false for an empty or storage-less spec.

func RootFrom

func RootFrom(ctx context.Context) (Root, bool)

RootFrom returns the confinement root stashed by Middleware, if any.

func RootFromToken

func RootFromToken(ctx context.Context) (Root, bool)

RootFromToken derives a confinement Root from the API token on ctx alone (its `root:` scope), without an *http.Request. The AI surface (/api/ai) does not pass through Middleware, so aiOps calls this to honor a token's path ceiling. Returns ok=false for unconfined tokens / cookie sessions.

func (Root) EnforcePath

func (r Root) EnforcePath(p string) (string, error)

EnforcePath is the exported form of enforce: validate/normalize a client path against the root, returning the qualified path or ErrOutOfRoot. The AI surface (aiOps) uses it directly since it bypasses Middleware.

func (Root) Within

func (r Root) Within(adapter, rel string) bool

Within reports whether a storage-relative path (no adapter prefix) is inside the root for the given adapter name.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL