Skip to main content
Version: 0.0.42

Required Secrets

Lakehousecat follows a secret-based configuration model: all sensitive values (API keys, access tokens, cloud credentials) are read by the operator from pre-created Kubernetes secrets. They are never placed in the Lakehousecat custom resource (CR).

This page lists every secret the operator can consume, how to create it, and what happens when one is missing.

Why secrets and not the CR?

The CR is a plain Kubernetes object — it ends up in kubectl get -o yaml, in your GitOps repository, in etcd, and in backups. Putting credentials there would expose them in all of those places. Keeping them in dedicated secrets lets you manage, rotate, and protect them with standard Kubernetes tooling (RBAC, encryption-at-rest, external secret managers).

How the operator handles missing secrets​

The operator never aborts a deployment because a secret is missing — it degrades gracefully:

  • The application always deploys.
  • A feature whose secret is missing is simply skipped, and the operator logs a warning and sets a status condition on the Lakehousecat resource.
  • For pre-configured models, a missing model secret skips only that model — every other model and the rest of the platform come up normally.

This means you can deploy first and add optional secrets later (see Adding or rotating a secret later).

Secret overview​

All secrets live in the instance namespace (spec.customer.namespace), except the handshake secret, which lives in the operator namespace (lhc-operator).

SecretRequired?Used forKeys
lhc-handshake-secretRequiredLicense handshake (all tiers)handshake-key
lhc-model-<id>-secretOptionalPre-configured model credentials (one per model)provider-specific (see below)
lhc-superset-mapbox-secretOptionalSuperset map visualizationsMAPBOX_API_KEY
lhc-storage-s3-secretOptionalExternal S3 object storage credentialsaccess-key, secret-key
lhc-oauth-<provider>-secretOptional*SSO / OAuth provider credentialsCLIENT_ID, CLIENT_SECRET
*OAuth secret-reference support is being rolled out — see OAuth / SSO below.

License handshake secret (required)​

Get your handshake key from portal.lakehousecat.com, then create the secret in the operator namespace:

kubectl create secret generic lhc-handshake-secret \
--from-literal=handshake-key=YOUR_HANDSHAKE_KEY_FROM_PORTAL \
-n lhc-operator

Reference it from the CR:

spec:
license:
handshakeSecretName: "lhc-handshake-secret"

Model credentials secrets​

Pre-configuring models in the CR is a convenience feature — the operator deploys the listed models automatically after the platform is up. You can always add models later through the application UI instead.

Each model's provider settings are read from a secret named lhc-model-<id>-secret (where <id> is the model's id), or from a custom name via spec.models[].credentialsSecretName. The CR itself carries only non-sensitive routing fields:

spec:
models:
models:
- id: "chat"
name: "azure-openai-chat"
providerType: "Azure" # OpenAI | Anthropic | Azure | AWS | Google
modelType: "Chat" # Chat | Speech-to-Text | Text-to-Speech | Image-Generation
isDefault: true
isEnabled: true
# credentials come from secret lhc-model-chat-secret

Secret keys per provider​

ProviderRequired keysOptional keys
OpenAIAPI_KEY, MODEL_IDORGANIZATION_ID
AnthropicAPI_KEY, MODEL_ID—
AzureAPI_KEY, ENDPOINT, DEPLOYMENT_NAME, API_VERSIONREGION, STT_LOCALES
AWSACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, MODEL_ID—
GoogleAPI_KEY, PROJECT_IDMODEL_ID, STT_LANGUAGE_CODES (comma-separated)

Create a model secret​

Using kubectl directly (Azure example for model id chat):

kubectl create secret generic lhc-model-chat-secret \
-n <instance-namespace> \
--from-literal=API_KEY=YOUR_AZURE_KEY \
--from-literal=ENDPOINT=https://your-resource.openai.azure.com/ \
--from-literal=DEPLOYMENT_NAME=chat \
--from-literal=API_VERSION=2024-02-01 \
--from-literal=REGION=swedencentral

Or with the helper script shipped in the operator repository:

NAMESPACE=<instance-namespace> MODEL_ID=chat PROVIDER=Azure \
API_KEY=YOUR_AZURE_KEY \
ENDPOINT=https://your-resource.openai.azure.com/ \
DEPLOYMENT_NAME=chat API_VERSION=2024-02-01 REGION=swedencentral \
./cli/create-model-secret.sh
note

If a model secret is missing or incomplete, that single model is skipped during deployment. Fix the secret and re-trigger a reconcile (see below) to deploy it.


Mapbox secret (Superset maps)​

Superset map charts need a Mapbox access token. Enable the feature in the CR and provide the token via the secret:

spec:
superset:
mapbox:
enabled: true # token comes from secret lhc-superset-mapbox-secret
kubectl create secret generic lhc-superset-mapbox-secret \
-n <instance-namespace> \
--from-literal=MAPBOX_API_KEY=pk.YOUR_MAPBOX_TOKEN

Or with the helper script:

NAMESPACE=<instance-namespace> MAPBOX_API_KEY=pk.YOUR_MAPBOX_TOKEN \
./cli/create-mapbox-secret.sh

If mapbox.enabled is true but the secret is absent, the platform starts normally and maps stay inactive until you add the token.


External S3 storage secret​

By default Lakehousecat deploys in-cluster SeaweedFS and needs no storage credentials. To use an external S3-compatible object store instead, provide the credentials via a secret and reference it from the CR:

spec:
objectStorage:
type: s3
region: "eu-west-1"
bucketPrefix: "mycompany-lhc"
credentialsSecretName: "lhc-storage-s3-secret"
kubectl create secret generic lhc-storage-s3-secret \
-n <instance-namespace> \
--from-literal=access-key=AKIA... \
--from-literal=secret-key=...

The same secret/keys apply to the legacy spec.storage.credentialsSecretName field.


OAuth / SSO secrets​

OAuth providers (Google, Microsoft Entra ID, generic OIDC, Auth0, AWS Cognito) are being migrated to the same secret-reference model: provider credentials will come from lhc-oauth-<provider>-secret (keys CLIENT_ID, CLIENT_SECRET), while non-sensitive fields (domain, tenant, discovery URL) stay in the CR.

kubectl create secret generic lhc-oauth-google-secret \
-n <instance-namespace> \
--from-literal=CLIENT_ID=your-client-id \
--from-literal=CLIENT_SECRET=your-client-secret
info

Until the migration is complete, follow the provider configuration shown in the model/auth guides. This page will be updated with the final field layout per provider.


Adding or rotating a secret later​

The operator reconciles on changes to the Lakehousecat CR. To enable a feature after the initial deployment:

  1. Create (or update) the secret in the instance namespace.
  2. Edit the CR to enable the feature (e.g. set mapbox.enabled: true, or add a spec.models entry). This triggers a reconcile.
# 1. create/rotate the secret
kubectl create secret generic lhc-superset-mapbox-secret \
-n <instance-namespace> \
--from-literal=MAPBOX_API_KEY=pk.NEW_TOKEN \
--dry-run=client -o yaml | kubectl apply -f -

# 2. trigger a reconcile (e.g. toggle the feature, or re-apply the CR)
kubectl apply -f lakehousecat.yaml
Restart for token changes

Some values (e.g. the Mapbox token consumed by Superset) are injected as environment variables and are only picked up when the pod starts. After rotating such a secret, the operator rolls the affected component on the next reconcile. Models are re-synced via API and need no restart.

Automating secret creation in a pipeline​

For production, create all required secrets before deploying the Lakehousecat CR — as a dedicated stage in your CI/CD pipeline (GitLab or GitHub), pulling values from your secret manager (AWS Secrets Manager, Google Secret Manager, Azure Key Vault, …). The operator assumes the secrets already exist and wires them in on the first reconcile.

Reference deployment repositories with ready-made pipelines for AWS EKS, Google GKE, Azure AKS, and on-premise are planned — they will create these secrets as part of the deployment flow.