Skip to main content

Kubernetes

A Helm chart lives in charts/orbit-object-console in the repository. It follows the Bitnami chart conventions — the same values layout, resource presets, probe overrides, security defaults and extraDeploy escape hatches — but keeps its template helpers local rather than depending on the bitnami/common chart, so it lints, templates and installs with no chart dependencies to fetch.

Prerequisites​

  • Kubernetes 1.23+
  • Helm 3.8+
  • PV provisioner support in the underlying infrastructure (when using SQLite)
  • An OIDC provider (Keycloak, Authentik, Auth0, Google, Azure AD, ...)

Install​

The console has no local passwords: sign-in is always delegated to an OIDC provider, so oidc.issuerUrl, oidc.clientId and a client secret are always required. The redirect URI registered with your provider must be <external-url>/auth/callback; the chart derives it from the ingress hostname when ingress.enabled=true, otherwise set oidc.redirectUri explicitly.

helm install orbit ./charts/orbit-object-console \
--namespace orbit --create-namespace \
--set oidc.issuerUrl=https://id.example.com/realms/main \
--set oidc.clientId=orbit-console \
--set oidc.clientSecret=<client-secret> \
--set ingress.enabled=true \
--set ingress.hostname=orbit.example.com

The chart refuses to render with a clear message when required values are missing, when persistence is disabled while SQLite is in use, or when replicaCount > 1 without an external database.

Renamed chart — install fresh, don't upgrade in place

The chart (and its container image) were renamed from s3-object-client to orbit-object-console. Renaming the chart renames the Kubernetes resources it creates (Deployment, Service, Secret, PVC, ServiceAccount, ...), so helm upgrade from an old s3-object-client release will not adopt the existing resources — it will either fail or create a conflicting, differently-named release. An existing release must be installed fresh under the new chart name rather than upgraded in place.

This also means the chart's auto-generated ENCRYPTION_KEY is not carried over: a fresh install generates a new one unless you explicitly set encryption.key or encryption.existingSecret to the previous value. See Security for what happens if the key changes.

Values overview​

By default the console stores its data in SQLite on a PersistentVolumeClaim — for more than one replica, point it at PostgreSQL with externalDatabase.enabled=true.

ModeValuesNotes
SQLite (default)persistence.enabled=trueSingle replica only; the database file lives on the PVC at persistence.mountPath
PostgreSQLexternalDatabase.enabled=trueRequired for replicaCount > 1; supply externalDatabase.host/user/password/database, or a full externalDatabase.url

Key application settings:

NameDescriptionDefault
oidc.issuerUrl / oidc.clientId / oidc.clientSecretOIDC provider (required)""
oidc.redirectUriRedirect URI; derived from the ingress hostname when empty""
encryption.key / encryption.existingSecretEncryption key for stored profile secrets; generated when empty""
sessionTtlSession cookie sliding expiry, in seconds28800
awsKeyless.enabledAllow connection profiles that authenticate with the pod's AWS identityfalse
replicaCountNumber of replicas (must be 1 with SQLite)1
ingress.enabled / ingress.hostnameIngress record generationfalse / orbit.local

The chart's full parameter tables (global, image, deployment, persistence, traffic exposure, autoscaling, and more) live in the chart README.

Ingress​

ingress:
enabled: true
hostname: orbit.example.com
ingressClassName: nginx
tls: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
oidc:
issuerUrl: https://id.example.com/realms/main
clientId: orbit-console
existingSecret: orbit-oidc

PostgreSQL with multiple replicas​

replicaCount: 3
externalDatabase:
enabled: true
host: postgresql.data.svc.cluster.local
user: orbit
database: orbit
existingSecret: orbit-postgresql
persistence:
enabled: false
pdb:
create: true
minAvailable: 2

Keyless AWS IAM​

A connection profile can authenticate as the server's own AWS identity instead of a stored access key/secret pair — no credentials to encrypt, rotate, or leak. This only applies to AWS S3 profiles; other S3-compatible backends still need a static access key/secret. It's controlled by awsKeyless.enabled, which sets AWS_KEYLESS_ENABLED=true on the container (see Configuration) and is off by default, because every signed-in user of the deployment who creates a keyless profile shares that same server identity — there's no per-user isolation.

Keyless profiles can optionally set a roleArn, in which case the server assumes that role via STS (AssumeRole) before talking to S3, rather than using its own identity directly.

Not covered by automated tests

The chart and application code support both delivery mechanisms below, but real EKS Pod Identity / IRSA / STS AssumeRole credential delivery is not exercised by the automated test suite — it requires a real EKS cluster and AWS IAM setup. Verify the identity resolves as expected in a staging environment before relying on it in production.

EKS Pod Identity​

With Pod Identity, the role association is made out of band (via the EKS Pod Identity Agent / aws eks create-pod-identity-association) against the pod's service account — no chart-side annotation needed:

awsKeyless:
enabled: true

IRSA​

With IRSA (IAM Roles for Service Accounts), annotate the service account with the role to assume:

awsKeyless:
enabled: true
serviceAccount:
create: true
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/orbit-object-console

Either way, grant the underlying IAM role only the S3 permissions your users need — it is shared by everyone who creates a keyless profile on this deployment.

Uninstalling​

helm uninstall orbit

The PersistentVolumeClaim is not deleted automatically — remove it manually if you no longer need the data:

kubectl delete pvc orbit-orbit-object-console-data