Self-hosted memory infrastructure

Long-term memory for your AI product,without the vendor lock-in.

HUPI is a drop-in gateway that gives any OpenAI-API-compatible client durable, fact-checked, and auditable memory across conversations — self-hosted, on your own Postgres, with any LLM vendor you choose.

Open source · Docker, Kubernetes & Helm ready · Bring your own Postgres

The problem

Every team building on top of LLM APIs runs into the same wall.

01

Memory resets every session

An AI's memory of a user normally disappears the moment a conversation ends, or gets capped by whatever fits in one context window — so your product either forgets, or pays to re-explain itself every time.

02

One vendor’s memory feature, one vendor’s lock-in

Bolt a memory feature onto a specific model provider and you’ve quietly tied your product’s entire history to that vendor — switching AI providers later means a data migration, not a config change.

03

Rolling your own inherits every hard problem at once

Building an ad hoc memory or RAG store for user data means you’re now also on the hook for encryption, multi-tenant isolation, and audit trails — from scratch, on your own timeline.

What HUPI is

Point your existing client at HUPI instead of the vendor. That's the integration.

HUPI is a small self-hosted server that speaks the standard OpenAI-compatible chat API on both sides. Change your client's base_url to point at HUPI instead of OpenAI, Anthropic, or whichever vendor you use today — nothing else in your application changes.

Underneath, HUPI enriches every turn with relevant memory before forwarding the request to whichever real LLM vendor is actually configured, and durably records the exchange afterward so future turns can draw on it.

before

base_url = "https://api.openai.com/v1"
one line changes

after

base_url = "https://your-hupi-host/v1"

Your client, prompts, and application code stay exactly as they are. HUPI forwards each request to the LLM vendor you've configured in providers.yaml.

Three pillars

What HUPI is built around.

Provider-independence

Switch from GPT to Claude to a locally hosted model — your memory doesn't move or need re-indexing beyond a one-time re-embed, because it's stored as plain decrypted text and metadata, not tied to any one vendor's format.

Integrity over convenience

Every “memory” the system asserts as fact is independently double-checked against its source text before being trusted. The system is designed to be honest about what it doesn't know, rather than confidently making things up about your own history.

Auditability

Every retrieval decision is recorded. You can ask, for any past AI response, "what exactly did it remember, and from where" and get a real, decryptable answer — not a guess.

How it works

Five steps, running quietly behind every conversation.

Click a step, or let it cycle on its own.

Capture

Every conversation turn is durably recorded the moment the AI replies — encrypted, by default, forever, until you deliberately delete it.

Security & multi-tenancy

What actually protects you if a key leaks or a database is compromised.

HUPI assumes any one layer can fail, so it doesn't rely on a single one. Here's what each independent layer actually does.

01

Scope filtering

Built into every query the application makes. Even with a leaked API key, an attacker can only act as the user that key belongs to — they see that user’s private memory and whatever teams that user belongs to, nothing else.

02

Row-level security

Enforced by Postgres itself, independent of the application code. Even if a future bug in the application forgets to filter a query correctly, the database refuses to return rows outside the requesting session’s declared scope — a second, independent safety net, verified with tests that deliberately try to break it.

03

Per-team encryption keys

Every team’s data is encrypted separately. Someone with raw access to the encrypted database contents cannot read any team’s data without that specific team’s key — a compromised key exposes only that one team, not the whole deployment.

04

Insert-only audit log

Every write, retrieval, investigation, and admin action lands in the same audit_log table, attributed to a named operator rather than a shared credential. It’s insert-only for the running application by design, so an attacker who compromises the app’s own database credential still can’t erase their own trail from it.

Deploy your way

Self-hosted. Bring your own Postgres. Container-native.

There's no hosted-only version of HUPI to sign up for. Nothing here bundles a database — you point HUPI at whatever Postgres (with the pgvector extension) you already run or operate, and TLS is handled by whatever reverse proxy or ingress controller already sits in front of your deployment.

Docker

One image contains every HUPI binary — the gateway runs as the default entrypoint, and the nightly consolidation job, self-check, export/import, and key-rotation tools all run from the same image via a command override. One thing to build, version, and scan.

Kubernetes manifests

Plain, numbered manifests under deploy/k8s/ — apply in order, including a migration Job, the gateway Deployment/Service/Ingress, and CronJobs for nightly consolidation and self-check.

Helm chart

The same resources, parameterized through values.yaml, with migrations wired in as a pre-install/pre-upgrade hook. Run helm template or --dry-run first to see exactly what it creates.

quick start

kubectl apply -f deploy/k8s/00-configmap-providers.yaml
kubectl apply -f deploy/k8s/01-secret-admin-db.yaml -f deploy/k8s/02-secret-app.yaml
kubectl apply -f deploy/k8s/03-migrate-job.yaml
kubectl apply -f deploy/k8s/04-deployment.yaml -f deploy/k8s/05-service.yaml

# or, with Helm:
helm install hupi deploy/helm/hupi \
  --set secrets.app.existingSecretName=hupi-app \
  --set secrets.adminDB.existingSecretName=hupi-admin-db

Give your AI product memory it doesn't have to trust blindly.

Self-hosted, open, and provider-independent — read the code, run it on your own infrastructure, point your own Postgres at it.