Helm Chart Configuration

Complete reference for all values.yaml options. Install AllureDeck from the OCI registry — no helm repo add required.

Prerequisites

Before installing AllureDeck, ensure you have:

  • Kubernetes 1.26+ — required for modern security context and policy APIs
  • Helm 3.10+ — required for OCI registry support
  • PostgreSQL 14+ — external database; the chart does not deploy PostgreSQL
Note: AllureDeck requires an externally managed PostgreSQL instance. Schema migrations run automatically on startup via Goose. See the PostgreSQL section for connection options and cloud provider examples.

Quick Start

The fastest path to a running installation. All three commands install directly from the OCI registry.

Minimal install
helm install alluredeck oci://ghcr.io/mkutlak/charts/alluredeck \
  --set api.config.databaseURL="postgres://user:password@postgres-host:5432/alluredeck?sslmode=require"
With custom values file
helm install alluredeck oci://ghcr.io/mkutlak/charts/alluredeck -f values.yaml
Pin a specific chart version
helm install alluredeck oci://ghcr.io/mkutlak/charts/alluredeck --version 0.4.0

API Configuration

Core settings for the Go API backend. Values under api.config.* are passed as environment variables to the container.

Key Description Default
api.image.repository API container image ghcr.io/mkutlak/alluredeck-api
api.image.tag Image tag "" (appVersion)
api.config.devMode Enable dev mode (verbose logging, relaxed security) "false"
api.config.logLevel Log level (debug, info, warn, error) "info"
api.config.storageType File storage backend (local or s3) "local"
api.config.databaseURL PostgreSQL connection string ""
api.config.keepHistory Enable test history tracking "true"
api.config.keepHistoryLatest Number of history entries to keep (0 = unlimited) "100"
api.config.keepHistoryMaxAgeDays Delete reports older than N days (0 = disabled) "0"
api.config.maxUploadSizeMb Max upload size in MB "100"
api.config.goMemLimit Go memory limit — set to ~80% of the memory limit "768MiB"
api.config.swaggerEnabled Enable Swagger UI at /swagger/index.html "false"
api.config.makeViewerEndpointsPublic Allow unauthenticated read access to viewer endpoints "false"
api.config.corsAllowedOrigins CORS origins list (auto-computed from ingress host if empty) []
api.config.checkResultsEverySeconds Polling interval for result processing "NONE"
api.config.trustXForwardedFor Trust X-Forwarded-For header from ingress "true"
api.kind Workload kind — Deployment or StatefulSet Deployment
api.replicaCount Number of API replicas 1
api.resources.requests.cpu CPU request 100m
api.resources.requests.memory Memory request 256Mi
api.resources.limits.memory Memory limit 1Gi

S3 / MinIO

When api.config.storageType is set to "s3", these values configure the S3-compatible storage backend. Works with AWS S3, MinIO, and any S3-compatible service.

Key Description Default
api.s3.endpoint S3 endpoint URL (leave empty for AWS S3) ""
api.s3.bucket Bucket name ""
api.s3.region AWS region "us-east-1"
api.s3.pathStyle Enable path-style addressing — required for MinIO "false"
api.s3.tlsInsecureSkipVerify Skip TLS certificate verification (dev only) "false"
api.s3.concurrency Upload concurrency for multipart transfers "10"
api.s3.existingSecret Name of a pre-existing Secret with S3_ACCESS_KEY and S3_SECRET_KEY ""
Tip: For EKS deployments, use IRSA (IAM Roles for Service Accounts) instead of static credentials. Set api.serviceAccount.annotations with the IAM role ARN and leave api.s3.existingSecret empty. See the EKS with IRSA example.

Security

Built-in role-based authentication with admin and viewer roles. All credential values are auto-generated as secure random secrets on first install and preserved across upgrades.

Key Description Default
api.security.enabled Enable JWT-based authentication "true"
api.security.user Admin username "admin"
api.security.password Admin password — auto-generated if empty ""
api.security.viewerUser Viewer username "viewer"
api.security.viewerPassword Viewer password — auto-generated if empty ""
api.security.jwtSecretKey HMAC signing key for JWT tokens — auto-generated if empty ""
api.security.jwtAccessTokenExpires Access token TTL in seconds "3600"
api.security.jwtRefreshTokenExpires Refresh token TTL in seconds "2592000"
api.security.existingSecret Use a pre-created Kubernetes Secret for all credentials ""
Warning: Setting api.security.enabled: "false" removes all authentication. Only do this in isolated development environments — never in production.

OIDC SSO

AllureDeck supports Single Sign-On via OpenID Connect. When enabled, users can log in with any compatible identity provider (Azure AD, Keycloak, Google, Okta, and others). OIDC login can coexist with the built-in admin/viewer accounts.

Key Description Default
api.oidc.enabled Enable OIDC SSO false
api.oidc.issuerUrl Identity provider discovery URL (e.g. https://login.microsoftonline.com/<tenant>/v2.0) ""
api.oidc.clientId OIDC client (application) ID ""
api.oidc.clientSecret Client secret — stored in a Kubernetes Secret ""
api.oidc.redirectUrl OAuth2 callback URL (must match IdP registration) ""
api.oidc.scopes Requested OIDC scopes (comma-separated) "openid,profile,email"
api.oidc.groupsClaim JWT claim name containing group memberships "groups"
api.oidc.adminGroups Comma-separated group IDs granted the admin role ""
api.oidc.editorGroups Comma-separated group IDs granted the editor role ""
api.oidc.defaultRole Role assigned to authenticated users not in any mapped group "viewer"
api.oidc.stateCookieSecret 32-byte AES key for encrypting OAuth2 state cookies — auto-generated if empty ""

For provider-specific setup instructions (Azure AD, Keycloak, Google, Okta), see the OIDC Authentication guide.

UI Configuration

Settings for the React frontend. The ui.config.apiUrl is automatically computed from the ingress host when ingress is enabled and the field is left empty.

Key Description Default
ui.image.repository UI container image ghcr.io/mkutlak/alluredeck-ui
ui.image.tag Image tag "" (appVersion)
ui.config.apiUrl API base URL — auto-computed from ingress host if empty ""
ui.config.appTitle Application title shown in the browser tab and header "AllureDeck"
ui.replicaCount Number of UI replicas 1
ui.resources.requests.cpu CPU request 50m
ui.resources.requests.memory Memory request 64Mi
ui.resources.limits.memory Memory limit 128Mi

Persistence

AllureDeck supports two storage backends: a local PersistentVolumeClaim for on-premises or single-node deployments, and S3-compatible object storage for cloud or multi-replica setups.

Local filesystem with PVC

Use api.kind: StatefulSet with a local PVC for stable volume binding. This is the recommended approach for single-replica on-prem deployments.

values.yaml — local PVC with StatefulSet
api:
  kind: StatefulSet
  config:
    storageType: "local"
  persistence:
    projects:
      enabled: true
      size: 10Gi
      storageClass: "standard"

S3 / MinIO with existingSecret

For S3 storage, set storageType: "s3" and provide credentials either inline or via an existing Secret.

values.yaml — S3 with existingSecret
api:
  kind: Deployment
  config:
    storageType: "s3"
  s3:
    endpoint: "https://minio.example.com"
    bucket: "alluredeck"
    region: "us-east-1"
    pathStyle: "true"
    existingSecret: "alluredeck-s3-credentials"

EKS with IRSA (no static credentials)

On EKS, annotate the ServiceAccount with the IAM role ARN. The AWS SDK picks up credentials automatically — no Secret needed.

values.yaml — EKS IRSA
api:
  kind: Deployment
  config:
    storageType: "s3"
  s3:
    bucket: "alluredeck-reports"
    region: "eu-west-1"
  serviceAccount:
    annotations:
      eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/alluredeck-s3

Ingress & TLS

The chart creates a single path-based Ingress resource routing all traffic through one hostname. CORS is automatically configured when the ingress host is set.

Path routing

Path Backend
/ UI (React frontend)
/api API (Go backend)
/swagger API — Swagger UI (only when api.config.swaggerEnabled: "true")

Ingress values

Key Description Default
ingress.enabled Create the Ingress resource false
ingress.className IngressClass name (e.g. nginx, traefik) ""
ingress.host Hostname for the Ingress rule ""
ingress.tls.enabled Enable TLS on the Ingress false
ingress.tls.secretName Name of the TLS Secret (created by cert-manager or manually) ""
ingress.annotations Additional annotations for the Ingress resource {}

TLS with cert-manager

values.yaml — Ingress with cert-manager TLS
ingress:
  enabled: true
  className: nginx
  host: allure.example.com
  tls:
    enabled: true
    secretName: alluredeck-tls
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/proxy-body-size: "200m"
Tip: When using nginx-ingress, set nginx.ingress.kubernetes.io/proxy-body-size to at least twice the value of api.config.maxUploadSizeMb. The default annotation value in the example above (200m) matches a 100 MB upload limit with headroom. Omitting this annotation causes nginx to reject large report uploads with a 413 error.

Network Policy

When enabled, the chart creates Kubernetes NetworkPolicy resources that restrict ingress to the API and UI pods. Only traffic from the ingress controller namespace is allowed — pod-to-pod communication is locked down by default.

values.yaml — NetworkPolicy
networkPolicy:
  enabled: true
  # Allow traffic from pods with this label in the ingress controller namespace
  ingressControllerSelector:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: ingress-nginx
      podSelector:
        matchLabels:
          app.kubernetes.io/name: ingress-nginx
Note: Adjust ingressControllerSelector to match your ingress controller's namespace and pod labels. For Traefik in the traefik namespace, replace the selector values accordingly.

PostgreSQL

AllureDeck requires an external PostgreSQL 14+ instance. The chart does not deploy a database. Schema migrations run automatically via Goose on every pod startup — no manual migration steps needed.

Connection string format

Connection string
postgres://username:password@hostname:5432/dbname?sslmode=require

Option A: Inline via api.config.databaseURL

Suitable for testing and development. The connection string is stored in the chart-managed Secret.

values.yaml — inline databaseURL
api:
  config:
    databaseURL: "postgres://alluredeck:secret@postgres.example.com:5432/alluredeck?sslmode=require"

Option B: existingSecret (recommended for production)

Reference a pre-existing Kubernetes Secret. The Secret must contain a databaseURL key. See the Secrets Management section for the full list of required keys.

values.yaml — existingSecret
api:
  security:
    existingSecret: alluredeck-credentials

CloudNativePG example

values.yaml — CloudNativePG
api:
  security:
    existingSecret: alluredeck-app  # Secret created by CloudNativePG cluster

AWS RDS example

values.yaml — AWS RDS
api:
  config:
    databaseURL: "postgres://alluredeck:secret@alluredeck.cluster-xyz.eu-west-1.rds.amazonaws.com:5432/alluredeck?sslmode=require"

Secrets Management

All credentials (admin/viewer passwords, JWT signing key, database URL) are managed in a single Kubernetes Secret. On first install the chart auto-generates secure random values for any field left empty. Existing values are preserved on helm upgrade.

For production deployments, use api.security.existingSecret to reference a Secret managed externally (Vault, AWS Secrets Manager, SOPS, etc.). The Secret must contain the following keys:

Key Description
adminUser Admin username
adminPassword Admin password (bcrypt-hashed by the API at startup)
viewerUser Viewer username
viewerPassword Viewer password
jwtSecretKey HMAC signing key for JWT tokens (min 32 bytes recommended)
jwtAccessTokenExpires Access token TTL in seconds
jwtRefreshTokenExpires Refresh token TTL in seconds
databaseURL PostgreSQL connection string

CSI driver example with extraResources

Use extraResources to inject a SecretProviderClass (Vault, AWS Secrets Manager, Azure Key Vault) alongside the chart manifests.

values.yaml — CSI SecretProviderClass via extraResources
api:
  security:
    existingSecret: alluredeck-credentials

extraResources:
  - apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: alluredeck-vault
    spec:
      provider: vault
      secretObjects:
        - secretName: alluredeck-credentials
          type: Opaque
          data:
            - objectName: adminPassword
              key: adminPassword
            - objectName: jwtSecretKey
              key: jwtSecretKey
            - objectName: databaseURL
              key: databaseURL
      parameters:
        vaultAddress: "https://vault.example.com"
        roleName: "alluredeck"
        objects: |
          - objectName: "adminPassword"
            secretPath: "secret/alluredeck"
            secretKey: "adminPassword"
          - objectName: "jwtSecretKey"
            secretPath: "secret/alluredeck"
            secretKey: "jwtSecretKey"
          - objectName: "databaseURL"
            secretPath: "secret/alluredeck"
            secretKey: "databaseURL"

Complete Examples

Ready-to-use values.yaml files for common deployment scenarios.

Minimal

The smallest possible configuration — only a database URL is required. Uses local storage, auto-generated credentials, no ingress.

values.yaml — minimal
api:
  config:
    databaseURL: "postgres://alluredeck:password@postgres-host:5432/alluredeck?sslmode=require"

Production with S3

Full production setup: S3 storage, custom credentials, path-based ingress with TLS, and NetworkPolicy.

values.yaml — production with S3
api:
  kind: Deployment
  replicaCount: 2
  config:
    storageType: "s3"
    logLevel: "info"
    keepHistory: "true"
    keepHistoryLatest: "200"
    maxUploadSizeMb: "150"
    goMemLimit: "768MiB"
  s3:
    bucket: "alluredeck-reports"
    region: "eu-west-1"
    existingSecret: "alluredeck-s3"
  security:
    existingSecret: "alluredeck-credentials"
  resources:
    requests:
      cpu: 200m
      memory: 512Mi
    limits:
      memory: 1Gi

ui:
  replicaCount: 2
  config:
    appTitle: "AllureDeck"
  resources:
    requests:
      cpu: 50m
      memory: 64Mi
    limits:
      memory: 128Mi

ingress:
  enabled: true
  className: nginx
  host: allure.example.com
  tls:
    enabled: true
    secretName: alluredeck-tls
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/proxy-body-size: "300m"

networkPolicy:
  enabled: true
  ingressControllerSelector:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: ingress-nginx
      podSelector:
        matchLabels:
          app.kubernetes.io/name: ingress-nginx

EKS with IRSA

EKS deployment using IAM Roles for Service Accounts — no static S3 credentials required. The AWS SDK picks up the role automatically via the projected token volume.

values.yaml — EKS with IRSA
api:
  kind: Deployment
  config:
    storageType: "s3"
    goMemLimit: "768MiB"
  s3:
    bucket: "alluredeck-reports"
    region: "eu-west-1"
    # No existingSecret — credentials come from IRSA
  serviceAccount:
    create: true
    annotations:
      eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/alluredeck-s3-role
  security:
    existingSecret: "alluredeck-credentials"
  resources:
    requests:
      cpu: 200m
      memory: 512Mi
    limits:
      memory: 1Gi

ui:
  config:
    appTitle: "AllureDeck"

ingress:
  enabled: true
  className: alb
  host: allure.example.com
  tls:
    enabled: true
    secretName: alluredeck-tls
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-west-1:123456789012:certificate/abc-123