Security model for obleth: key hashing, admin token hardening, TLS architecture, and fail-open tradeoffs.
obleth never stores raw API keys. When a key is created:
sk_{24 random bytes hex-encoded}.api_keys.key_hash) and cached in Redis (obleth:key:{hash}).On each request, the gateway hashes the incoming Authorization: Bearer ... value and looks up the hash. A stolen database or Redis dump does not expose valid API keys.
The Management API and control plane are protected by a single bearer token (OBLETH_ADMIN_TOKEN). This is intentionally simple — it's a service-to-service credential, not a user-facing RBAC system.
Hardening:
openssl rand -hex 32:9090 at the network layer (firewall, Kubernetes NetworkPolicy)obleth itself does not terminate TLS. TLS should be terminated at the edge by HAProxy or your Ingress controller.
Internet
| HTTPS (TLS)
v
HAProxy / Ingress
| HTTP (internal only)
v
obleth :8080
Never expose obleth's data plane or admin port directly to the internet. They are HTTP-only.
For internal service-to-service communication (e.g., control plane to Management API within a cluster), TLS is optional and typically omitted for pods within the same Kubernetes namespace.
Two fields in the database contain credentials:
| Field | Table | What it is |
|---|---|---|
api_key | models | Upstream API key for the inference backend |
auth_header | mcp_servers | Auth header value for MCP server calls |
These are stored as plaintext in Postgres. Mitigations:
pgcrypto) if your compliance requirements demand it.Hash = SHA-256(raw_key_bytes)
Redis key = "obleth:key:" + hex(Hash)
The hash is computed in the obleth-proxy crate before any Redis lookup. The raw key value never touches the network after the initial creation response.
With OBLETH_FAIL_OPEN=true (default): if Redis is unavailable and the key is not in the moka cache, the request is served with no budget check. This means:
With OBLETH_FAIL_OPEN=false: requests are rejected when Redis is unavailable. This provides strict budget enforcement at the cost of availability during Redis outages.
Choose based on your requirements:
| Surface | Exposure | Mitigations |
|---|---|---|
Data plane :8080 | Public (via HAProxy/Ingress) | API key auth, TLS at edge |
Admin API :9090 | Internal only | Bearer token, network restriction |
Metrics :9091 | Internal only (Prometheus) | Network restriction |
| Postgres | Internal only | Strong password, encryption at rest |
| Redis | Internal only | Strong password (if enabled), network restriction |
| ClickHouse | Internal only | Strong password, network restriction |