Vault Config Operator

repository·main·Indexed 41 days ago

https://github.com/redhat-cop/vault-config-operator

A Kubernetes operator that automates the configuration of HashiCorp Vault resources, including Authentication Engines, Policies, Secret Engines, and Identities, via CRDs. It provides a high-fidelity interface mirroring the Vault API and uses namespace-local service accounts for secure authentication.

Tokens
169.1K
Snippets
364
Records
687
Agent score
47%

What's inside Vault Config Operator

  1. Overview of Vault Config Operator

    main

    The Vault Config Operator is designed to automate the setup of Vault configurations within Kubernetes, specifically enabling pods to consume secrets effectively.

    It operates on two core principles:

    1. High-fidelity API: The Custom Resource Definitions (CRDs) provided by the operator map field-for-field to the official HashiCorp Vault APIs. This ensures that the operator does not make assumptions about your specific configuration workflow and provides a direct interface to Vault's extensive capabilities.
    2. Security-first approach: To prevent credential leaks, the operator itself is granted no permissions within Vault. Instead, all APIs exposed by the operator use a local service account (local to the namespace where the API resource exists) to authenticate to Vault.

    Note on Permissions: For a user in a namespace to successfully configure Vault via the operator, a service account in that same namespace must have been previously granted the necessary permissions within Vault.

  2. Manage AWS Auth Engine via Custom Resources

    main

    The vault-config-operator allows you to manage HashiCorp Vault's AWS authentication method declaratively using three Kubernetes Custom Resource Definitions (CRDs). This enables automated configuration of client settings, identity mappings, and IAM/EC2 roles within Vault.

    Supported CRDs

    1. AWSAuthEngineClientConfig: Configures the global client settings for the AWS auth method at auth/{path}/config/client. This includes connection details and AWS credentials.
    2. AWSAuthEngineIdentityConfig: Configures identity-specific settings (like IAM or EC2 aliases) at auth/{path}/config/identity. Note that deleting this CR will not delete the configuration in Vault.
    3. AWSAuthEngineRole: Defines specific Vault roles at auth/{path}/role/{name}. These roles bind AWS identities (IAM or EC2) to Vault policies and capabilities.

    Immutability and Validation

    • spec.path: This field is immutable across all three CRD types. To change the Vault auth path, you must delete and recreate the resource.
    • spec.name: For AWSAuthEngineRole, the spec.name field is immutable.
    • Credential Validation: The operator validates credential sources for AWSAuthEngineClientConfig during admission.
  3. Configure Kubernetes Authentication Engine via KubernetesAuthEngineConfig

    main

    The KubernetesAuthEngineConfig Custom Resource (CR) is used to configure the settings for a Kubernetes authentication mount in Vault. When a KubernetesAuthEngineConfig CR is created, the operator writes the configuration to Vault at the path auth/{path}/{name}/config.

    Key Configuration Fields

    • path: The mount path of the Kubernetes auth engine (e.g., test-k8s-auth).
    • kubernetesHost: The URL of the Kubernetes API server (e.g., https://kubernetes.default.svc:443).
    • disableLocalCAJWT: Boolean flag to control local CA JWT usage.
    • useOperatorPodCA: Boolean flag to determine if the operator's Pod CA should be used.

    Lifecycle and Cleanup

    • Reconciliation: Successful reconciliation sets ReconcileSuccessful=True on the CR.
    • Deletion: Deleting a KubernetesAuthEngineConfig CR results in immediate deletion from Kubernetes without performing a cleanup in Vault (the CR is marked as IsDeletable=false).
    metadata:
      name: test-kaec-mount
    path: test-k8s-auth
    kubernetesHost: https://kubernetes.default.svc:443
    disableLocalCAJWT: true
    useOperatorPodCA: false
  4. Understand OPM `index add` deprecation

    main

    In OPM v1.73.0, the opm index add command is deprecated but remains functional. Using this command will emit a deprecation warning directing users toward File-Based Catalogs (FBC).

    Important: While the command is deprecated, the flags and behavior remain unchanged for now:

    • --container-tool
    • --mode
    • --tag
    • --bundles
    • --from-index (or --from-index-opt)

    Do not attempt to migrate to FBC as part of a simple tool upgrade; FBC migration is a separate architectural change. Accept the warning during make catalog-build for the current scope.

  5. Verify Identity Token resource lifecycle and deletion behavior

    main

    The operator handles the deletion of Identity Token resources differently based on their type and the IsDeletable property:

    Resource TypeDeletion BehaviorVault State After Deletion
    IdentityTokenRoleIsDeletable=trueRole is removed from Vault; CR is removed from K8s
    IdentityTokenKeyIsDeletable=trueKey is removed from Vault; CR is removed from K8s
    IdentityTokenConfigIsDeletable=falseCR is removed from K8s; Vault config persists (no finalizer cleanup)

    When updating an IdentityTokenKey (e.g., changing the algorithm from RS256 to ES256), the operator should reflect the change in Vault and increase the ObservedGeneration of the Custom Resource.

  6. Manage Kubernetes Auth Roles via KubernetesAuthEngineRole

    main

    The KubernetesAuthEngineRole resource defines specific roles within a Kubernetes authentication mount.

    Key Behaviors:

    • Path Resolution: Roles are written to Vault at auth/{spec.path}/role/{metadata.name}. Note that spec.path must include the full mount path segment.
    • Lifecycle: This resource is deletable (IsDeletable: true). Deleting the CR will trigger a finalizer that removes the role from Vault.
    • Namespace Binding: You can bind roles to specific namespaces using two methods:
      1. Explicit List: Provide a list of names in spec.targetNamespaces.targetNamespaces.
      2. Label Selector: Provide a spec.targetNamespaces.targetNamespaceSelector (e.g., using matchLabels). The controller watches Kubernetes Namespace objects and dynamically updates the Vault role if namespaces gain or lose matching labels.
    • Validation Rules:
      • You must provide exactly one of targetNamespaceSelector or targetNamespaces. Providing both or neither will result in a validation error.
      • The spec.path field is immutable after creation.
    • Dynamic Updates: The controller watches Namespace resources to ensure the bound_service_account_namespaces in Vault stays in sync with the Kubernetes cluster state.
    apiVersion: redhatcop.redhat.io/v1alpha1
    kind: KubernetesAuthEngineRole
    metadata:
      name: test-kaer-role-selector
    spec:
      authentication:
        path: kubernetes
        role: policy-admin
      path: test-k8s-auth/test-kaec-mount
      policies:
        - vault-admin
      targetServiceAccounts:
        - default
      targetNamespaces:
        targetNamespaceSelector:
          matchLabels:
            database-engine-admin: "true"
  7. Identity OIDC Resource Lifecycle and Dependency Chain

    main

    The Vault Config Operator manages four interconnected Identity OIDC Custom Resources (CRs). Because these resources interact with Vault's internal identity OIDC subsystem, they must be managed in a specific order to satisfy dependencies.

    Dependency Order

    To ensure successful creation, resources must be created in this order:

    1. IdentityOIDCScope: Defines the scope (template and description).
    2. IdentityOIDCAssignment: Maps entity IDs and group IDs.
    3. IdentityOIDCClient: References an IdentityOIDCAssignment.
    4. IdentityOIDCProvider: References an IdentityOIDCScope.

    Deletion Order

    To avoid orphaned resources or dependency errors during cleanup, resources must be deleted in reverse dependency order:

    1. IdentityOIDCProvider
    2. IdentityOIDCClient
    3. IdentityOIDCAssignment
    4. IdentityOIDCScope
  8. Configure the AWS Auth Engine using CRDs

    main

    The AWS Auth Engine is managed via three distinct Custom Resource Definitions (CRDs) to provide a 1:1 mapping to the Vault API. To set up AWS authentication, you must configure the client, identity, and specific roles.

    Core CRD Types

    1. AWSAuthEngineClientConfig: Configures the connection to Vault's AWS auth engine, including credential resolution (access keys/secret keys) and retry logic.
    2. AWSAuthEngineIdentityConfig: A simple configuration for identity management with enum-validated alias fields.
    3. AWSAuthEngineRole: Defines the specific authentication roles (IAM or EC2) and their associated constraints (e.g., TTLs, bound accounts, or instance tags).

    Important Implementation Notes

    • Credential Resolution: AWSAuthEngineClientConfig resolves credentials via RootCredentialConfig.
    • Drift Detection: The operator uses a StandardVaultResource reconcile pattern for client configurations. Note that due to how IsEquivalentToDesiredState handles secret keys, client configurations backed by secrets may be re-applied during steady-state reconciles even if the readable fields match Vault.
  9. Verify VaultSecret update behavior

    main

    To validate that the VaultSecret reconciler correctly handles updates, follow this pattern in integration tests:

    1. Ensure a VaultSecret has been successfully reconciled (check that ReconcileSuccessful=True).
    2. Update a field in the VaultSecret spec (for example, changing a template or a secret path).
    3. Verify that the reconciler detects the change and updates the corresponding Kubernetes Secret.
    4. Confirm that the ReconcileSuccessful condition is updated with a new ObservedGeneration.
  10. Lifecycle of Identity OIDC Resources

    main

    The Identity OIDC implementation manages four distinct resource types that must be created and managed in a specific dependency order to ensure successful reconciliation in Vault.

    Creation Order (Dependency Chain):

    1. IdentityOIDCScope
    2. IdentityOIDCAssignment
    3. IdentityOIDCClient
    4. IdentityOIDCProvider

    Lifecycle Operations:

    • Creation: Verifies that descriptions, templates, and resource existence are reflected in Vault. For IdentityOIDCClient, this includes verifying client_type, key, and the server-generated client_id. For IdentityOIDCProvider, it verifies that scopes_supported contains the expected scopes.
    • Update: Modifies existing resources (e.g., changing a description) and verifies that Vault reflects the change and the Kubernetes ObservedGeneration increases.
    • Deletion: Resources must be deleted in reverse order to avoid dependency errors: IdentityOIDCProvider $\rightarrow$ IdentityOIDCClient $\rightarrow$ IdentityOIDCAssignment $\rightarrow$ IdentityOIDCScope.
  11. Compare Audit and AuditRequestHeader reconciler types

    main

    The operator uses two distinct reconciler patterns for these types. Understanding which one is being used is critical for knowing which Vault API is targeted and how lifecycle methods (Create/Delete) are implemented.

    • Audit: Uses the VaultAuditResource reconciler (NewVaultAuditResource). It targets the Vault Sys() API (e.g., EnableAuditWithOptions, ListAudit, DisableAudit). It implements both VaultObject and VaultAuditObject interfaces.
    • AuditRequestHeader: Uses the standard VaultResource reconciler (NewVaultResource). It targets the Vault Logical() API for standard Read/Write/Delete operations on its path. It implements only the VaultObject interface.
    | Type | Reconciler | Vault API | Create Method | Delete Method |
    |------|-----------|-----------|---------------|---------------|
    | **Audit** | `VaultAuditResource` (`NewVaultAuditResource`) | `Sys()` API — EnableAuditWithOptions / ListAudit / DisableAudit | Device enable | Device disable |
    | **AuditRequestHeader** | `VaultResource` (`NewVaultResource`) | `Logical()` API — standard Read/Write/Delete on path | Logical Write | Logical Delete |
  12. Verify Vault cleanup after KubernetesSecretEngineConfig deletion

    main
    The KubernetesSecretEngineConfig resource supports the IsDeletable flag. When IsDeletable is set to true, the Vault Config Operator is responsible for cleaning up the associated Vault resource when the Custom Resource (CR) is deleted from Kubernetes. This ensures that no orphaned configurations remain in Vault after the Kubernetes resource is removed.