Verification

These receipts describe the deployed state verified on 2026-08-29. Re-run the probes after any image, credential, network, nginx, certificate, or OIDC change.

Configuration and image receipt

  • sudo -n docker compose config --quiet: exit 0
  • image references:
    • six services carry an @sha256: manifest digest
    • no image is resolved by a mutable tag alone
    • LobeHub resolves to version 2.2.15 at digest sha256:9186fbb2a1cd593eada518560695e1f14f0fa570ed987ba1bf1b3008456422ca
  • published sockets:
    • 127.0.0.1:52100 to LobeHub 3210
    • 127.0.0.1:52101 to RustFS 9000
    • no published PostgreSQL, Redis, SearXNG, or RustFS console socket

Compose status receipt

sudo -n docker compose ps -a produced the expected state shape:

ContainerServiceReceipt
lobeloberunning, healthy
lobe-postgrespostgresqlrunning, healthy
lobe-redisredisrunning, healthy
lobe-rustfsrustfsrunning, healthy
lobe-searxngsearxngrunning
lobe-rustfs-initrustfs-initexited 0

The rustfs-init exit receipt proves the one-shot dependency completed after creating or confirming bucket lobe and applying bucket.config.json. SearXNG has no Compose healthcheck, so running is its expected status annotation.

Loopback and public-route receipt

  • application loopback root on port 52100: success
  • RustFS loopback /health on port 52101: success
  • https://lobe.loca.zone/: LobeHub response
  • https://wiki.lobe.loca.zone/: public wiki response
  • missing wiki route: 404
  • nginx configuration test: success

Reprobe without response bodies:

cd ~/dev/lobe
sudo -n docker compose config --quiet
sudo -n docker compose ps -a
curl -fsS http://127.0.0.1:52100/ >/dev/null
curl -fsS http://127.0.0.1:52101/health >/dev/null
curl -fsS https://lobe.loca.zone/ >/dev/null
curl -fsS https://wiki.lobe.loca.zone/ >/dev/null
test "$(curl -sS -o /dev/null -w '%{http_code}' https://wiki.lobe.loca.zone/not-a-real-page)" = 404
sudo -n nginx -t

LiteLLM network and scope receipt

The probe ran from the Lobe container, not from the host:

  • network route: lobe to lllm-proxy:4000 over lllm_default
  • authenticated GET /v1/models: exactly fast, free, and oss-120b
  • configured display allowlist: -all,+fast,+oss-120b,+free
  • request for an unlisted model: HTTP 403

This proves both the container-network route and the lobe virtual-key boundary. A host-side LiteLLM response would not prove either property.

The following probe consumes the container’s existing key without printing it:

sudo -n docker exec -i lobe node <<'NODE'
(async () => {
  const base = 'http://lllm-proxy:4000/v1';
  const headers = { Authorization: `Bearer ${process.env.OPENAI_API_KEY}` };
  const response = await fetch(`${base}/models`, { headers });
  if (!response.ok) throw new Error(`models status ${response.status}`);
  const ids = (await response.json()).data.map((model) => model.id).sort();
  console.log(ids.join('\n'));
 
  const denied = await fetch(`${base}/chat/completions`, {
    method: 'POST',
    headers: { ...headers, 'content-type': 'application/json' },
    body: JSON.stringify({
      model: 'not-permitted',
      messages: [{ role: 'user', content: 'scope probe' }],
      max_tokens: 1,
    }),
  });
  console.log(`unlisted=${denied.status}`);
  if (ids.join(',') !== 'fast,free,oss-120b' || denied.status !== 403) process.exit(1);
})().catch((error) => {
  console.error(error.message);
  process.exit(1);
});
NODE

Expected output contains only the three model IDs and unlisted=403; it never contains the key.

OIDC receipt

  • anonymous LobeHub login offered Authelia and no email or password registration
  • authorization initiation reached an Authelia flow=openid_connect page for client lobe
  • redirect URI matched https://lobe.loca.zone/api/auth/callback/authelia
  • requested scopes were openid, profile, and email
  • no invalid_client, invalid_redirect_uri, or invalid_scope marker appeared
  • native Better Auth owns the application session
  • nginx contains no auth_request on the application vhost

The issuer discovery endpoint was reachable from the Lobe container. No password, hash, client secret, or session token was printed to establish this receipt.

Certificate receipt

One Certbot lineage named lobe.loca.zone was presented by all three TLS vhosts:

  • SAN: lobe.loca.zone
  • SAN: wiki.lobe.loca.zone
  • SAN: s3.lobe.loca.zone
  • expiry: 2026-11-27

Redaction-safe reprobe:

for host in lobe.loca.zone wiki.lobe.loca.zone s3.lobe.loca.zone; do
  echo "$host"
  openssl s_client -connect "$host:443" -servername "$host" </dev/null 2>/dev/null \
    | openssl x509 -noout -ext subjectAltName -enddate
done

Each connection must show the same three-name SAN set.

Object-storage receipt

  • rustfs-init: exited 0
  • bucket: lobe
  • policy: anonymous s3:GetObject
  • consequence: uploaded object URLs are publicly readable
  • write boundary: writes remain signed
  • public route: S3 API only; console disabled
  • nginx object limit: 128m

The backup proof for object durability is an inspected mc mirror, not this policy receipt. See backups-restore.