Skip to content

[Security]: Define External Secrets namespace isolation best practices #414

Description

@Matthiator

📝 Summary

Kubara should define and integrate a secure default pattern for namespace-scoped secret access with External Secrets Operator.

PR #370 introduces namespace-isolated OpenBao access for the T Cloud Public provider. This works well because OpenBao can enforce backend-side Kubernetes auth roles and policies, so a workload in one namespace can only read the matching OpenBao path.

For managed secret backends outside the cluster, especially STACKIT Secrets Manager, the same security boundary is less clear. If the backend credentials used by a ClusterSecretStore can read all secrets in a shared instance, Kubernetes namespace isolation alone does not prevent an ExternalSecret from requesting another namespace's remote key.

Relevant upstream guidance:
https://external-secrets.io/latest/guides/security-best-practices/

Related context:
#370

🎯 Motivation

The Problem

External Secrets Operator recommends caution with cluster-wide resources such as ClusterSecretStore and ClusterExternalSecret, and suggests using namespace isolation, ClusterSecretStore match conditions, restricted RBAC, scoped installations, network policies, and policy engines such as Kyverno or Gatekeeper.

Kubara currently has two different situations:

  • OpenBao: namespace isolation can be enforced in the backend through Kubernetes auth and OpenBao policies.
  • STACKIT Secrets Manager: if path-scoped backend policies are not available, a single shared secret-manager instance/user may allow broader read access than intended.

Other cloud providers show the preferred target model:

  • AWS Secrets Manager can restrict access through IAM roles and policies on secret ARNs or name prefixes.
  • Azure Key Vault can restrict access through Azure RBAC or access policies, commonly with a vault per application/environment.
  • Google Secret Manager can grant secretAccessor on individual secrets or narrower identity scopes.

This suggests that the hard security boundary should be enforced by the secret backend whenever possible. Kubernetes admission policies are useful guardrails, but they are not equivalent to backend-side authorization.

Goals

  • Define the recommended Kubara best practice for External Secrets access isolation.
  • Keep the OpenBao model as the preferred hard-isolation pattern where backend policies are available.
  • Document the recommended model for cloud providers with backend IAM/RBAC support:
    • AWS: namespace/team-specific IAM role and secret ARN or prefix policy.
    • Azure: namespace/team/application-specific identity and Key Vault scope, preferably vault per application/environment where appropriate.
    • Google Cloud: namespace/team-specific Kubernetes/GCP identity with secretAccessor only on required secrets or tightly scoped projects.
  • Evaluate secure STACKIT patterns, especially:
    • one STACKIT Secrets Manager instance or credential boundary per namespace/team, exposed via namespaced SecretStore
    • one shared STACKIT Secrets Manager instance plus Kyverno/Gatekeeper policies that restrict ExternalSecret.spec.data[].remoteRef.key to the requesting namespace prefix
  • Decide what Kubara should generate by default and what should remain opt-in.
  • Document the security properties and limitations clearly.
  • Align generated Helm/Terraform templates, docs, and tests with the chosen model.

Out of Scope

  • Implementing a custom secret backend provider.
  • Adding backend-side policy features that STACKIT Secrets Manager does not expose.
  • Automatically migrating existing installations without an explicit migration design.

💡 Proposal

Design

Investigate and implement one or more supported patterns:

  1. OpenBao-backed clusters

    Keep the current namespace-isolated design from PR feat: add T Cloud Public CCE provider support #370:

    • namespaced SecretStore per consuming namespace
    • Kubernetes auth against OpenBao
    • OpenBao policy limiting reads to secret/<namespace>/*
    • explicit exceptions only for intentionally shared secrets, such as image pull secrets
  2. Cloud providers with backend IAM/RBAC

    Document and optionally template the preferred hard-isolation model:

    • namespaced SecretStore per namespace/team
    • one backend identity per namespace/team
    • backend policy that allows only the matching secret path, prefix, vault, project, or explicit secret list
    • Kyverno/Gatekeeper only as an additional validation layer, not as the primary security boundary
  3. STACKIT with stronger isolation

    Evaluate generating or documenting a stronger isolation model:

    • create separate STACKIT Secrets Manager instances or users per namespace/team where possible
    • create a namespaced SecretStore for each namespace
    • keep credentials scoped to that namespace/team boundary
    • avoid a broad shared ClusterSecretStore for tenant-controlled workloads
  4. STACKIT with shared instance and admission control

    If a single shared STACKIT Secrets Manager instance remains necessary, add guardrails:

    • require remote keys to follow a namespace prefix convention, for example <namespace>/...
    • provide Kyverno or Gatekeeper policy examples that deny ExternalSecret resources when remoteRef.key does not match the namespace prefix
    • optionally restrict ClusterSecretStore usage with spec.conditions
    • restrict RBAC so application teams cannot edit arbitrary SecretStore, ClusterSecretStore, or cross-namespace secret resources
    • document that this is weaker than backend-enforced policy because it depends on Kubernetes admission/RBAC controls
  5. Docs and validation

    Update the nearest relevant docs to explain:

    • hard backend isolation vs. Kubernetes/admission guardrails
    • recommended defaults per provider
    • known limitations for managed secret managers without path-scoped policies
    • when to use SecretStore vs. ClusterSecretStore
    • when to use Kyverno/Gatekeeper policies

Alternatives Considered

  • Keep a single ClusterSecretStore for all providers.

    • Simple, but it can overstate namespace isolation when the backend credential has broad read permissions.
  • Rely only on Kyverno/Gatekeeper.

    • Useful as a guardrail, but not equivalent to backend-side policy enforcement.
  • Require OpenBao for every provider.

    • Stronger security model, but removes support for users who intentionally rely on managed secret managers.

✅ Checklist

  • I have searched existing issues
  • This is not a duplicate

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions