Skip to content
PaloNexus
Request access Request

Secrets

PaloNexus is same-image-everywhere: no secret is ever baked into a container image, and none are in the rendered Kustomize set. This page catalogs every secret the platform handles, where it lives, and how to deliver it safely.

SecretWhere it livesUsed byNotes
OPENAI_API_KEY (model-broker-secrets)palonexus nsmodel-broker onlyThe real provider key — the only place it exists. No agent pod ever holds it; agents call the broker, the broker calls the provider.
Issuer key ISSUER_PRIVATE_KEY_B64agent-idp nsagent-idpThe did:web issuer Ed25519 private key. Signs Membership/Delegation Verifiable Credentials (VCs) and Security Token Service (STS) tokens. Must be stable across restarts or every previously-issued VC fails to verify. Unset → agent-idp generates an ephemeral dev key and warns.
Logto M2M LOGTO_M2M_APP_ID / _SECRETseeder env / seed-logtoseed-logto, portal seed surfaceOptional — sample-data seeding. Machine-to-machine credentials for the Logto Management API, used only by the optional sample-data seeder; the platform runtime does not require them. Scope to the Management API resource only. Logto is the supported workforce identity provider (IdP); any standard OpenID Connect (OIDC) / SCIM (System for Cross-domain Identity Management) provider fits the same seam — see IdP Support Model.
Agent workload tokens (PALONEXUS_AGENT_TOKEN)per-agentthe agent + SDKThe agent’s own bearer for live egress decisions. Short-lived; prefer the agent STS / SPIFFE over a long-lived static token.
Agent identity material (did:key priv + Membership VC)per-pod emptyDiragent + egress-sidecarWritten by the agent at bootstrap, read by the sidecar. Never leaves the pod; rotated by re-provisioning.
SDK API keys (PALONEXUS_API_KEY, pn_live_…/pn_test_…)developer / CIthe SDK facadeScope and rotate per environment; pn_test_… for sandbox, pn_live_… for prod.
Registry / store DSNs (REGISTRY_DB_URL, IDP_DB_URL)control-plane / agent-idppersistence layerContain DB passwords. With the postgres component, CloudNativePG generates the *-app secret and the component wires the data source name (DSN) in — the password is never written by hand.
portal-ts-auth (TS_AUTHKEY)palonexus nsportalOptional Tailscale auth key for tailnet ingress. Deploy succeeds without it (use port-forward).

The catalog above is the what; this matrix is the operational view used by a cluster rollout — every cluster Secret/env, its namespace, the consumer, what it unlocks, and the fail-closed default when it’s absent. Grounded against the live palonexus-doks reference rollout (ops-portal-deploy-note.md). The guiding rule: absence never crash-loops the platform — it degrades to the safe (closed) state.

Secret / envNamespace · componentConsumed byEnablesFail-closed default if absent
model-broker-secretsOPENAI_API_KEYpalonexusmodel-brokera real allowed model call returns 200broker won’t serve model calls; deploy still succeeds
agent-idp-secretsISSUER_PRIVATE_KEY_B64agent-idpagent-idpstable VC/STS signing across restartsephemeral dev key + warn; restart breaks prior VCs
agent-idp-keysIDP_KEY_HASH_SALTagent-idpagent-idp /v1/keyssalted hashing of SDK API keys at restkey store unusable / unsalted; mint+verify fails closed
simulate-operatorSIMULATE_OPERATOR_TOKENpalonexus (control-plane and portal backend-for-frontend, BFF, same value)control-plane dry-run gate + portal /simulatethe /authz dry-run (“Live decision” simulator); per-request X-Palonexus-Simulate-Operator must matchempty = dry-run disabled entirely
logto-m2m → 5× LOGTO_*palonexus via components/portal-seed-logto (optional: true)portal /settings/logto + /settings/seedseed-from-UI against a live tenant; form becomes read-only / Ops-managedfalls back to 0600 file / offline mode; never crash-loops
SEED_LOGTO_DIR = /opt/seed-logtoportal image and agent-idpportal seed spawn + agent-idp authority_previewlocate seed_logto.py / nsr_seeder + sample-org manifestsagent-idp /v1/authority/preview503 authority_engine_unavailable
SEED_LOGTO_PYTHON = /opt/seedvenv/bin/python3portal imageportal seed spawnthe venv interpreter for child_process.spawnspawn falls back to python3 on PATH (ENOENT on a plain node:* image)
ALLOW_LOGTO_SEED = trueportal (palonexus)portal seed routethe apply/reseed/cleanup mutationsseed mutations disabled (plan/preview only)
agent-dburiapps (per-agent, optional: true)agent podsdurable LangGraph checkpointer (human-in-the-loop, HITL, survives restart)MemorySaver (in-process HITL only)

Optional — sample-data seeding. Rows marked ᴰ (logto-m2m, SEED_LOGTO_DIR, SEED_LOGTO_PYTHON, ALLOW_LOGTO_SEED) are secrets for the optional seed tooling — they load the sample identity model into a Logto tenant for evaluation and testing and are not required for PaloNexus to run. A production deployment connects the organization’s workforce IdP instead — see IdP Support Model.

The base deploy succeeds without these — the broker just won’t serve model calls and agent-idp uses an ephemeral key. Apply the real ones separately:

Terminal window
cp deploy/kustomize/base/model-broker/secret.example.yaml \
deploy/kustomize/base/model-broker/secret.yaml # edit OPENAI_API_KEY (gitignored)
kubectl apply -f deploy/kustomize/base/model-broker/secret.yaml
# Stable issuer key (generate once, store in the secret manager):
kubectl -n agent-idp create secret generic agent-idp-issuer \
--from-literal=ISSUER_PRIVATE_KEY_B64="$(your-keygen)"
Section titled “Recommended: External Secrets or sealed-secrets”

Hand-applied Secrets are fine for a demo but don’t belong in a real cluster. Use one of:

  • External Secrets Operator — keep the source of truth in Vault / AWS Secrets Manager / DigitalOcean Secrets and sync into Kubernetes Secrets. The cluster never stores the canonical value.

    apiVersion: external-secrets.io/v1beta1
    kind: ExternalSecret
    metadata: { name: model-broker-secrets, namespace: palonexus }
    spec:
    secretStoreRef: { name: vault-backend, kind: ClusterSecretStore }
    target: { name: model-broker-secrets }
    data:
    - secretKey: OPENAI_API_KEY
    remoteRef: { key: palonexus/model-broker, property: openai_api_key }
  • Sealed-secrets — commit an encrypted SealedSecret to Git; only the in-cluster controller can decrypt it. Good when GitOps is the source of truth.

    Terminal window
    kubeseal --format yaml < secret.yaml > sealed-secret.yaml # safe to commit

Either way the rendered manifest set stays secret-free, and rotation is a manager-side operation.

  • Issuer key is the sensitive one: rotating it invalidates every VC signed by the old key. Rotate by publishing the new public key at the did:web document, then cutting over — agents re-provision to get VCs under the new key. Plan this as a coordinated upgrade.
  • Provider key / M2M / API keys rotate independently with no platform-wide impact — update the secret, restart the consumer (broker / seeder), or roll a new SDK key.
  • Agent tokens should be short-lived via the STS so rotation is automatic.