Skip to content
Query.Farm
Talk with Us

Authentication

Require authentication for a worker served over HTTP, and read the caller’s identity inside your functions.

Authentication is an HTTP-only concern

Auth applies only to the HTTP transport. A subprocess or Unix-socket worker is launched by the engine and runs co-located and trusted — there’s no remote caller to authenticate — so it always runs as AuthContext.anonymous(). Reach for authentication when you serve over HTTP.

TransportAuth behavior
HTTP, with auth configuredValidated per request; the caller’s AuthContext is propagated to your functions
HTTP, no auth configuredAll requests anonymous
Subprocess / Unix socketAlways AuthContext.anonymous() (co-located, trusted)
TCPAlways AuthContext.anonymous()and not trusted. See the warning below.
TCP is the one unauthenticated remote transport

Subprocess and Unix-socket workers are anonymous because they’re co-located. A TCP worker is anonymous for a different reason: the raw Arrow-IPC framing carries no auth and no encryption, so anyone who can reach the port can call every function. Bind it to loopback or a trusted network — and use HTTP the moment the network isn’t one.

The authentication machinery — the AuthContext, the authenticate callback, and the HTTP middleware that runs it per request — is provided by vgi-rpc, the RPC framework VGI runs on. VGI wires it into the HTTP server and surfaces the resulting AuthContext to your functions. So this page covers the VGI integration; for the full model (the callback contract, the AuthContext type, mTLS, OAuth discovery) see vgi-rpc’s Auth & Context reference.

Authentication is fully optional — unconfigured, every request is anonymous.

The quickest setup is static bearer tokens via an environment variable — comma-separated token=principal pairs:

VGI_BEARER_TOKENS="token1=alice,token2=bob" vgi-serve my_worker.py --http

Unauthenticated requests get HTTP 401; authenticated ones carry the principal in an AuthContext. (Each pair splits on the first =, so a principal may contain =, but a token must not contain = or ,.)

A function opts in by declaring the auth context; the framework injects it per call.

Scalar functions — annotate a compute parameter with Auth:

from typing import Annotated
import pyarrow as pa
from vgi import ScalarFunction, Param, Returns, Auth
from vgi.auth import AuthContext

class WhoAmI(ScalarFunction):
  @classmethod
  def compute(
      cls,
      x: Annotated[pa.Int64Array, Param(doc="rows to label")],
      auth: Annotated[AuthContext, Auth()],
  ) -> Annotated[pa.StringArray, Returns()]:
      auth.require_authenticated()          # raises if anonymous
      return pa.array([auth.principal] * len(x))

Table / aggregate / buffering functions — read params.auth_context (also available at bind time on the bind params):

from vgi.table_function import TableFunctionGenerator

class SecureTable(TableFunctionGenerator):
  @classmethod
  def process(cls, params, state, out):
      if not params.auth_context.authenticated:
          raise PermissionError("Authentication required")
      # … produce output …

AuthContext carries principal, authenticated, and domain, and require_authenticated() raises PermissionError when anonymous. The full type lives in vgi-rpc — Auth & Context.

For real deployments, validate JWTs against a JWKS endpoint instead of static tokens. Set the issuer and audience (pip install vgi-python[oauth]):

VGI_JWT_ISSUER="https://auth.example.com/" \
VGI_JWT_AUDIENCE="my-api" \
vgi-serve my_worker.py --http
VariableDescription
VGI_JWT_ISSUERJWT issuer URL (enables JWT validation)
VGI_JWT_AUDIENCEExpected audience(s), comma-separated
VGI_JWT_JWKS_URIJWKS endpoint (auto-discovered from the issuer if omitted)
VGI_OAUTH_RESOURCEResource URL for RFC 9728 OAuth metadata (and related VGI_OAUTH_* vars)

When both VGI_BEARER_TOKENS and VGI_JWT_ISSUER are set, JWT validation is tried first, falling back to bearer lookup. The full OAuth/JWKS surface — RFC 9728 resource metadata, OIDC id_token mode, and the discovery flow — is documented in vgi-rpc’s OAuth discovery reference.

  • Custom schemes — pass your own authenticate callback to make_wsgi_app(authenticate=…) / create_app(...) to implement any scheme; env vars are then ignored. See vgi-rpc’s Auth & Context.
  • Mutual TLS — client-certificate auth is a vgi-rpc capability; see Mutual TLS.
  • Behind a reverse proxy — when the proxy terminates the only public listener, override Worker.resolve_token() to expose a token-introspection route, and advertise proof enforcement with VGI_PROXY_PROOF_MODE. Both are covered under Deployment caps and proxies.