Skip to content

Feat/vault eso secrets support - #20

Open
Uttah wants to merge 3 commits into
gitroomhq:mainfrom
Uttah:feat/vault-eso-secrets-support
Open

Uttah wants to merge 3 commits into
gitroomhq:mainfrom
Uttah:feat/vault-eso-secrets-support

Conversation

@Uttah

@Uttah Uttah commented May 21, 2026

Copy link
Copy Markdown

feat: add Vault + ESO secrets support with Reloader integration

Description

Implements the Vault → ENV в поде workflow described in SECRETS_WF_REQUIREMENTS.md.

When vault.enabled: true, secrets are sourced from HashiCorp Vault KV v2 via External Secrets Operator: ESO authenticates to Vault using the pod's ServiceAccount JWT (kubernetes auth method), pulls all keys from the configured KV path and materialises them as a native Kubernetes Secret. The Deployment picks up that Secret via envFrom. Stakater Reloader watches the Secret and automatically restarts the pod on rotation.

When vault.enabled: false (default), the chart behaves exactly as before — Secret is rendered from values.yaml. No breaking changes.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Deployed to a live Kubernetes 1.30 cluster with Vault (bank-vaults operator, KV v2), ESO and Stakater Reloader installed.

  • SecretStore vault-backend — status Valid
  • ExternalSecret — status SecretSynced, Kubernetes Secret created with all keys from Vault KV v2 path secret/b2b/<app>/backend/prod/env
  • Pod started with env vars sourced entirely from Vault (confirmed via application logs — app connected to DATABASE_URL and REDIS_URL values stored in Vault, not in values.yaml)
  • Stakater Reloader annotation present on pod template, pod restarts automatically on Secret update
  • Backward compatibility confirmed: vault.enabled: false renders native Secret from values as before, no regressions

Test Configuration:

  • Kubernetes version: 1.30.1
  • Helm version: 3.x
  • ESO version: external-secrets.io/v1
  • Vault: 1.17.6 (bank-vaults operator)
  • Stakater Reloader: installed cluster-wide

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • Backward compatibility preserved (vault.enabled: false by default)

Additional Information

  • Does this change introduce any new Kubernetes resource types? Yes
    SecretStore (external-secrets.io/v1), ExternalSecret (external-secrets.io/v1) — both rendered only when vault.enabled: true

  • Does this change modify any existing Kubernetes resource types? Yes

    • Deployment — added conditional secret.reloader.stakater.com/reload annotation on pod template; optional psql-ca volume + volumeMount (vault.psqlCa.enabled)
    • Secret — wrapped in {{- if not .Values.vault.enabled }} to avoid conflict with the ESO-owned Secret when Vault flow is active
  • Are there any changes to the values.yaml file? Yes
    Added vault.* block:

    vault:
      enabled: false          # true = Vault/ESO flow; false = legacy Secret from values
      server: "http://vault-bv.vault:8200"
      mount: "secret"
      role: ""                # must match Vault kubernetes auth role name (= SA name)
      path: ""                # KV v2 path without mount prefix
      refresh: "1h"
      psqlCa:
        enabled: false
        path: "certs/psql-ca"
        refresh: "1h"
        mountPath: "/var/www/.postgresql/root.crt"
  • Does this change require any specific Kubernetes permissions or RBAC changes? Yes

    Cluster-side prerequisites (one-time, outside the chart):

    • Vault kubernetes auth method enabled with kubernetes_host and disable_iss_validation: true
    • ServiceAccount vault in namespace vault must have ClusterRoleBinding to system:auth-delegator — required for Vault to validate SA tokens via TokenReview API
    • Vault default policy must retain capabilities for auth/token/lookup-self, auth/token/renew-self, auth/token/revoke-self, sys/capabilities-self — otherwise ESO gets 403 immediately after login
    • ESO installed in namespace external-secrets with SecretStore / ExternalSecret CRDs available
    • Stakater Reloader installed and watching secret.reloader.stakater.com/reload annotation

    Per-instance Vault configuration:

    • Vault policy read-<app> with read capability on secret/data/b2b/<app>/backend/prod/env
    • Vault kubernetes role <app> with bound_service_account_names: [<app>], bound_service_account_namespaces: [<app>], policies: [read-<app>], ttl: 1h
    • Secrets placed in Vault at path secret/b2b/<app>/backend/prod/env (KV v2)
  • Are there any changes to chart dependencies? Yes

    postgresql and redis dependency repositories switched from https://charts.bitnami.com/bitnami to oci://registry-1.docker.io/bitnamicharts — the current official Bitnami OCI registry. Chart versions unchanged.

  • Have you updated the CHANGELOG.md file? No — no CHANGELOG exists in the repository.

alex.fedotov added 2 commits May 21, 2026 10:16
- Add vault.* section in values.yaml with enabled flag (false by default,
  keeps backward compatibility with native Secret from values)
- Wrap postiz-secret.yaml in {{- if not .Values.vault.enabled }} so it is
  not rendered when Vault flow is active
- Add postiz-secretstore.yaml: SecretStore vault-backend (kubernetes auth,
  configurable server/mount/role)
- Add postiz-externalsecret.yaml: ExternalSecret for env vars (dataFrom
  extract) and optional second ExternalSecret for psql-ca cert; target.name
  matches the existing envFrom secretRef in Deployment so no Deployment
  changes are needed for the basic case
- Add Reloader annotation secret.reloader.stakater.com/reload to
  Deployment pod template (conditional on vault.enabled), listing all
  Vault-backed Secrets so pods restart automatically on secret rotation
- Add optional psql-ca volume + volumeMount in Deployment
  (vault.psqlCa.enabled)
- Switch bitnami dependency repositories to
  oci://registry-1.docker.io/bitnamicharts
@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@Uttah has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 59 minutes before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dd2532f9-967e-4226-bb7a-09f26cd7664c

📥 Commits

Reviewing files that changed from the base of the PR and between 5d6a9de and f506072.

📒 Files selected for processing (7)
  • .gitignore
  • charts/postiz/Chart.yaml
  • charts/postiz/templates/postiz-deployment.yaml
  • charts/postiz/templates/postiz-externalsecret.yaml
  • charts/postiz/templates/postiz-secret.yaml
  • charts/postiz/templates/postiz-secretstore.yaml
  • charts/postiz/values.yaml
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant