View Markdown

Security posture

On this page

Pointsman holds provider credentials and processes application prompts. Its security boundary includes the gateway, administrative access, backing stores, optional external checks and the network around them. This page describes controls and their limits in the qualified source; deployment settings still matter.

If an attacker gets the database#

Virtual keys are stored as HMAC-SHA256(pepper, raw) digests. POINTSMAN_AUTH_PEPPER is held outside the database. A database dump alone does not supply that pepper or the original random key. The gateway refuses startup without the required pepper, and PepperFingerprintGuard detects an unexpected change rather than silently invalidating every existing key. Protect and back up the pepper separately; changing it is not ordinary key rotation.

Registry snapshots hold a provider credentialRef, such as env:OPENAI_API_KEY, rather than copying the resolved provider secret into routing metadata. This protection does not cover arbitrary secrets pasted into other fields. Treat database backups, configuration exports and administrative access as sensitive.

If a key leaks#

Virtual keys carry an environment, credential identifier, random secret and checksum. The filter rejects malformed or wrong-environment keys before lookup. The checksum only detects format errors; the digest comparison establishes identity.

Revoke a leaked key or rotate it through the supported workflow. Rotation records a grace deadline and communicates the remaining window through response headers. Identity caches and invalidation bound revocation propagation; do not assume instantaneous global revocation. Expiry is checked against the clock even for cached metadata. See authentication design and key management.

If prompts are sensitive#

OpenTelemetry content capture is off by default (pointsman.observability.otel.capture-content=false). When enabled, it is byte-capped by capture-content-max-bytes. Review all retention, trace, request-inspection and export settings before sending sensitive prompts; disabling one trace option is not a claim that no component retains content.

Cache namespaces bind tenant scope. Anonymous evaluation traffic uses a per-request salt for cache scope, preventing different anonymous users from reusing each other's answers. That deliberately removes cross-request anonymous cache benefit.

External moderation, webhooks, hosted embeddings, optional context processing and model providers can receive content. Choose these services and their credentials according to the deployment's data-handling requirements. Local or external guardrails have false positives and false negatives; they do not prove that all sensitive content was removed.

If the control plane is reachable#

Administrative mutations require server-side authorization. The scoped authorization core is enabled by default; the scope-tree application request path is separately disabled by default. Read policy-based authorization for inherited grants, delegation, tenant boundaries and the compatibility fallbacks. Policy previews do not prove every subject restriction is enforced on live requests.

Administrative authentication is separate from application keys. Browser sessions use an HttpOnly, SameSite=Strict cookie and CSRF-token checks. HTTP Basic remains an automation authentication path. The gateway does not issue a browser Basic challenge, and mutating control-plane requests also undergo origin checks: cross-site fetches and mismatched origins are refused. Headerless machine clients remain supported. Basic credentials must still travel over TLS.

/admin/**, sensitive actuator paths and /internal/** have controls distinct from the bearer-authenticated /v1/** API. A hidden dashboard button is not authorization. A compromised platform administrator can read and alter configuration, provider destinations and policies; an audit trail helps detection but cannot make that administrator unprivileged.

Feedback ownership is also enforced at the gateway. Only the key that owns an eligible decision may submit its rating; anonymous decisions cannot acquire an owner through a shared anonymous rate-limit bucket. Learner state is scoped by the gateway's attributed tenant/task, not an arbitrary caller-supplied tenant name. These checks do not extend across an exposed learner endpoint.

What the stack publishes#

Surface Base Compose posture Deployment responsibility
Gateway and dashboard Published ingress ports TLS, ingress restrictions and strong application/admin credentials
PostgreSQL and Redis No default host-published store ports Private networking, credentials, persistence and least privilege
RedisInsight, Prometheus and Grafana No default host-published management ports Keep administrative tools restricted
Policy service Private Compose network Do not expose its unauthenticated mutation endpoints
Optional developer/tracing/demo ports Loopback-bound overlays/profiles Do not treat development exposure as a production boundary

The gateway allows unauthenticated health, info and Prometheus endpoints. Hiding the standalone Prometheus server does not hide /actuator/prometheus on the gateway port. Restrict those routes at ingress if their operational information should be private.

Replace sample PostgreSQL, Grafana and gateway-admin credentials. The gateway has separate REDIS_CACHE_PASSWORD and REDIS_COUNTER_PASSWORD bindings for its cache and counter clients. Configure matching server-side authentication when using them; a client password variable alone does not secure Redis. The qualified v1 profile also separates counter and cache stores and constrains destructive counter-store operations. Inspect the chosen Compose overlay rather than assuming the evaluation stack has the same protections.

Store isolation is essential: direct access to Redis or PostgreSQL can bypass controls implemented in the gateway. A non-root gateway container does not prevent an attacker from connecting directly to an exposed store.

Outbound destinations#

Application request fields do not choose arbitrary gateway destinations. Tool calls are forwarded, not executed; image URLs are passed to providers rather than fetched by the gateway. Provider connections and external checks are configured by the operator or authorized administrator.

EgressPolicy validates admin-configured provider/guardrail destinations at write time and use time. Default decisions reject link-local/metadata, private, loopback and other disallowed address classes unless explicitly permitted. An unresolved destination can be stored as unverified but cannot be activated until it resolves to permitted addresses. All resolved addresses are considered. URL user-info is rejected, reserved headers cannot override the host, and supported clients do not follow redirects into a different destination.

These checks do not provide network egress isolation. Clients do not pin a checked DNS result for every future socket, so DNS changes/rebinding and other process-originated traffic still require network controls. Deploy-time service URLs are trusted operator configuration and are not all judged by this policy. Public internet destinations are generally permitted; this is not a default-deny provider allowlist.

First-boot dependencies can also connect out: the gateway may download DJL native libraries and bundled RedisInsight can fetch content. OPT_OUT_TRACKING=true disables DJL telemetry in the gateway image. See startup dependencies.

Use deployment-level egress rules for the destinations the process may reach, while retaining required DNS and service access. An internal: true Docker network plus HTTP proxy variables is not a supported universal egress-proxy configuration for these clients.

What this does NOT protect against#

  • A compromised gateway process or administrator. They can access credentials and content available to that process or role. Reduce their permissions and monitor changes.
  • Plaintext secrets in an unrecognized extra-header field. Credential-shaped names are refused and export/audit surfaces redact values, but name checks cannot recognize every secret. Use supported credential references. A short change digest is not a confidentiality guarantee for low-entropy values.
  • An exposed policy service. It has no independent API authentication in this deployment. Anyone reaching its mutation endpoints can affect learning. Keep its service network private and its environment separate from provider/admin secrets.
  • Provider or auxiliary-service compromise. Content sent to another service is subject to that service's boundary.
  • Perfect content classification. Native rules, optional classifiers and external services can miss harmful content or refuse benign content. Whole-response checks also have different coverage on buffered and live streaming paths.
  • Universal recovery or availability. A counter loss, unavailable authoritative identity store or unverifiable spend cap can correctly refuse work. Do not disable those controls to make health look green.

Read deployment, guardrail design, policy service design and known limitations alongside this page. Report vulnerabilities through the repository's private security-reporting instructions; do not include credentials or private prompts in public issues.

Pointsman v1 candidate documentation Source: 0e09f5e7

Search guides, reference pages and architecture.

Documentation

Open full-size image