Skip to content

Secrets Management Service (SMS)

The Secrets Management Service (SMS) acts as a broker between the DataRobot platform and a client-managed secret storage backend, ensuring the following:

  • Stores only secret metadata (identifiers and schema references) in DataRobot's database.
  • Routes all secret values, such as credentials, API keys, and secure configurations, to and from the client's own secret storage.
  • Ensures sensitive data is never stored in the DataRobot platform.

The Secrets Management Service is available starting with DataRobot 11.9. SMS supports the following secret storage backends:

You configure exactly one backend per deployment.

Requirements

Before enabling the Secrets Management Service, you must fulfill the following requirements:

  • A supported secret storage backend is deployed and reachable over HTTPS from the DataRobot cluster.
  • Credentials or an authentication method for the backend are provisioned for DataRobot.

For backend-specific requirements, see the sections below

HashiCorp Vault

If you are using HashiCorp Vault as your backend service, you must meet the following requirements:

  • A HashiCorp Vault (OSS or Enterprise) instance is deployed and accessible over HTTPS from the DataRobot cluster.
  • The KV v2 secrets engine is enabled.
  • An authentication method is configured for DataRobot:

    • For AppRole authentication, the auth method is enabled in Vault, and a Role ID and Secret ID are provisioned.
    • For Kubernetes or JWT authentication, the auth method must be enabled in Vault before use.
  • A base path is allocated in Vault for DataRobot secrets.

  • (Optional) If Vault uses a private CA, the CA certificate is available in PEM format.
  • (Optional) If using Vault Enterprise, the target namespace is identified. If not set, this defaults to the Vault root namespace.

Vault policy

HashiCorp Vault operates on a deny-by-default model, so you must attach a policy that grants the following permissions to the Vault role configured for SMS (or the token, if using token authentication):

Path Required capabilities
<kv-base-path>/* create, read, update, delete, list
auth/token/lookup-self read
auth/token/renew-self update

If you plan to enable scoped token support, also grant:

Path Required capabilities
auth/token/create create, update

The following HCL policy satisfies these requirements. Replace <kv-base-path> with the mount path allocated for DataRobot secrets:

path "<kv-base-path>/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "auth/token/lookup-self" {
  capabilities = ["read"]
}

path "auth/token/renew-self" {
  capabilities = ["update"]
}

Attach this policy to your auth method role (AppRole, Kubernetes, or JWT) or directly to the token before proceeding with enablement.

Azure Key Vault

If you are using Azure Key Vault as your backend service, you must meet the following requirements:

  • An Azure Key Vault instance is deployed and reachable over HTTPS from the DataRobot cluster. Note its vault URI (for example, https://<vault-name>.vault.azure.net/).
  • An Azure (Microsoft Entra ID) application registration or managed identity is provisioned for DataRobot, and you have its tenant ID and client (application) ID.
  • The application is granted permission to manage secrets in the Key Vault (see Key Vault permissions).
  • An authentication method is selected and its credentials are provisioned:

    • For client secret authentication, a client secret (password) is generated for the application registration.
    • For client certificate authentication, a certificate is registered on the application, and the PEM bundle (certificate and private key) is available.
    • For workload identity authentication, the cluster has an OIDC issuer enabled and the Azure Workload Identity webhook installed. A federated identity credential must also link from the Kubernetes service account in DataRobot to the application registration.
  • A secret name prefix is chosen for DataRobot's secrets. A prefix is required for Azure Key Vault: it must start with a letter and contain only letters, digits, and hyphens, with a maximum of 80 characters.

Key Vault permissions

SMS creates, reads, and deletes secrets in the Key Vault. Using Azure RBAC, assign the built-in Key Vault Secrets Officer role to the application registration (or managed identity) in DataRobot, scoped to the target Key Vault. This role grants all of the secret operations SMS requires:

Operation Purpose
Get Read secret values requested by DataRobot.
Set Create and update secrets.
Delete Soft-delete secrets that DataRobot removes.
Purge Permanently remove soft-deleted secrets during best-effort background cleanup.

If your Key Vault uses access policies instead of Azure RBAC, grant the equivalent secret permissions (Get, Set, Delete, and Purge).

Note

Azure Key Vault soft-deletes a secret before purging it. After deleting a secret, SMS attempts a best-effort purge in the background. If purge protection is enabled on the vault, or the purge does not succeed, the secret remains recoverable until the vault's retention window (7–90 days) expires, after which Azure purges it automatically.

Enablement

SMS is disabled by default. To enable it, set global.secret-mgmt-service.enabled: true, then configure one of the supported storage backends, as described in the following sections:

global:
  secret-mgmt-service:
    enabled: true

Only one backend can be configured at a time. SMS selects the backend based on which configuration block you populate under storage and fails to start if more than one—or none—are configured.

When SMS is enabled, the chart automatically sets ENABLE_SECRET_MGMT_SERVICE_INTEGRATION: true on the core service, which causes DataRobot to route all credentials, API keys, and other sensitive configuration through SMS for storage in the configured backend. If you need to keep the SMS service running without activating this routing—for example, to retain access to secrets already stored in a backend—you can explicitly disable the integration:

core:
  config_env_vars:
    ENABLE_SECRET_MGMT_SERVICE_INTEGRATION: false

HashiCorp Vault

Configure the Vault connection under storage.vault:

secret-mgmt-service:
  storage:
    vault:
      addr: "https://<vault-address>:<vault-port>"
      auth_method: <auth-method>  # approle | k8s | jwt | token
      mount_path: "<kv-base-path>/"
      # namespace: "<vault-enterprise-namespace>"  # optional: Vault Enterprise only
Field Description
addr The HTTPS address of your Vault instance.
auth_method The authentication method: approle, k8s, jwt, or token.
mount_path KV v2 base path allocated for DataRobot secrets.
namespace (Optional) The Vault Enterprise namespace. If not set, this defaults to the root namespace.

If Vault uses a private CA, provide the CA certificate via a Kubernetes Secret; see Custom CA certificate.

Then add the auth-method-specific configuration described in the following sections.

AppRole authentication

Add the approle block under storage.vault:

secret-mgmt-service:
  storage:
    vault:
      approle:
        role_id: "<role-id>"
        mount_path: "approle/"
        token_wrapping: "false"

The AppRole Secret ID is sensitive credential material. The recommended approach is to provide it via a Kubernetes Secret, referencing it under app.secrets as the VAULT_APPROLE_SECRET_ID environment variable:

secret-mgmt-service:
  app:
    secrets:
      - name: VAULT_APPROLE_SECRET_ID
        valueFrom:
          secretKeyRef:
            name: <approle-credentials-secret>
            key: secret-id

Alternatively, you can set it directly in your values file:

secret-mgmt-service:
  storage:
    vault:
      approle:
        secret_id: "<secret-id>"

Kubernetes authentication

SMS presents its Kubernetes service account token; Vault verifies it by calling the Kubernetes API server directly. This authentication method is recommended for Kubernetes-native Vault deployments.

Add the k8s block under storage.vault:

secret-mgmt-service:
  storage:
    vault:
      k8s:
        mount_path: "kubernetes/"
        role: "<vault-role-name>"

JWT authentication

SMS presents its Kubernetes service account token; Vault verifies it independently using public keys from the Kubernetes OIDC discovery endpoint without a live call to the Kubernetes API server per request.

Add the jwt block under storage.vault:

secret-mgmt-service:
  storage:
    vault:
      jwt:
        mount_path: "jwt/"
        role: "<vault-role-name>"

Token authentication

Provide a static Vault token via a Kubernetes Secret, referencing it under app.secrets as the VAULT_TOKEN environment variable:

secret-mgmt-service:
  app:
    secrets:
      - name: VAULT_TOKEN
        valueFrom:
          secretKeyRef:
            name: <vault-credentials-secret>
            key: token

Alternatively, you can set it directly in your values file:

secret-mgmt-service:
  storage:
    vault:
      token: "<vault-token>"

Custom CA certificate

If your Vault instance uses TLS signed by a private CA, provide the PEM-encoded CA certificate via a Kubernetes Secret, referencing it under app.secrets as the VAULT_CA_CERT environment variable:

secret-mgmt-service:
  app:
    secrets:
      - name: VAULT_CA_CERT
        valueFrom:
          secretKeyRef:
            name: <vault-ca-cert-secret>
            key: ca-cert

Alternatively, you can set it directly in your values file as a single-line PEM string with \n-escaped newlines:

secret-mgmt-service:
  storage:
    vault:
      ca_cert: "-----BEGIN CERTIFICATE-----\n<base64-encoded-certificate>\n-----END CERTIFICATE-----"

Scoped token support

By default, SMS authenticates to Vault once and reuses the resulting token for all secret operations. Enabling scoped token support changes this behavior: SMS creates a short-lived child token with a limited TTL and only the policies required for each individual operation, discarding it immediately after use. This limits the blast radius if a token is ever compromised, but increases load on the Vault token API because a new token is created and revoked for every secret operation.

Enable this option only if your security requirements justify the additional Vault overhead.

To enable scoped tokens, ensure the Vault policy includes auth/token/create permissions, then add the following to your values override:

secret-mgmt-service:
  storage:
    vault:
      scoped_token_enabled: true
      scoped_token_policies:
        - "<policy-name>"  # policy to attach to each scoped token

Azure Key Vault

Configure the Key Vault connection under storage.azure, along with the required secret name prefix:

secret-mgmt-service:
  storage:
    secret_name_prefix: "<prefix>"  # required for Azure Key Vault
    azure:
      addr: "https://<vault-name>.vault.azure.net/"
      tenantId: "<azure-tenant-id>"
      authMethod: <auth-method>  # client_secret | client_certificate | workload_identity
      clientId: "<azure-application-client-id>"
Field Description
secret_name_prefix Prefix for every secret name stored in the Key Vault. Required for Azure Key Vault. Must start with a letter, contain only letters, digits, and hyphens, and be at most 80 characters. This field is a sibling of azure under storage, not nested inside it.
addr The Key Vault URI, for example https://<vault-name>.vault.azure.net/. Must be an HTTPS URL.
tenantId The Azure (Microsoft Entra ID) tenant ID.
authMethod The authentication method: client_secret, client_certificate, or workload_identity.
clientId The application (client) ID of the application registration or managed identity. Required for all authentication methods.

Then add the auth-method-specific configuration described in the following sections.

Client secret authentication

Add the servicePrincipal block under storage.azure:

secret-mgmt-service:
  storage:
    azure:
      authMethod: client_secret
      servicePrincipal:
        clientSecret: "<client-secret>"

The client secret is sensitive credential material. The recommended approach is to provide it via a Kubernetes Secret, referencing it under app.secrets as the AKV_SP_CLIENT_SECRET environment variable:

secret-mgmt-service:
  app:
    secrets:
      - name: AKV_SP_CLIENT_SECRET
        valueFrom:
          secretKeyRef:
            name: <akv-credentials-secret>
            key: client-secret

When you supply the client secret via app.secrets, omit servicePrincipal.clientSecret from your values file.

Client certificate authentication

Provide a certificate registered on the application registration. The PEM bundle—the certificate and its private key—is sensitive credential material. The recommended approach is to provide it via a Kubernetes Secret, referencing it under app.secrets as the AKV_CLIENT_CERTIFICATE_PEM environment variable:

secret-mgmt-service:
  storage:
    azure:
      authMethod: client_certificate
  app:
    secrets:
      - name: AKV_CLIENT_CERTIFICATE_PEM
        valueFrom:
          secretKeyRef:
            name: <cert-secret-name>
            key: <cert-secret-key>

For example, create the secret from a local bundle file:

kubectl create secret generic <cert-secret-name> \
  --from-file=bundle.pem=<path-to-bundle.pem> \
  --namespace datarobot

In this example, set name to <cert-secret-name> and key to bundle.pem.

Workload identity authentication

Workload identity is recommended for production Kubernetes deployments. SMS authenticates using an Azure federated identity credential bound to its Kubernetes service account, so no client secret or certificate is stored in the cluster.

This method requires that the cluster has an OIDC issuer enabled, the Azure Workload Identity mutating admission webhook installed, and a federated identity credential that links SMS's Kubernetes service account to the application registration. The webhook is what injects the projected service account token and AZURE_* environment variables into the SMS pod; without it, the annotations the chart applies (below) have no effect.

Workload identity requires no values beyond the common ones described above (set authMethod to workload_identity and provide clientId).

When authMethod is workload_identity and the chart creates the service account (serviceAccount.create: true, the default), it automatically annotates the service account with azure.workload.identity/client-id and labels the pod with azure.workload.identity/use: "true". If you use an existing service account (serviceAccount.create: false), you must add the azure.workload.identity/client-id: <clientId> annotation to that service account yourself.

Apply the configuration

After updating your values override file, perform a Helm upgrade:

helm upgrade datarobot datarobot/datarobot-prime \
  -f your-values-override.yaml \
  --namespace datarobot

Verification

After the upgrade completes, verify that the SMS pod is running:

kubectl get pods -n datarobot -l role=secret-mgmt-service-app

Confirm the pod has passed its readiness probe:

kubectl get pod -n datarobot -l role=secret-mgmt-service-app -o jsonpath='{.items[0].status.conditions[?(@.type=="Ready")].status}'

The output should be True. If the pod is not ready, check the logs for backend connectivity or authentication errors:

kubectl logs -n datarobot -l role=secret-mgmt-service-app

Post-enablement

Once the service is running, DataRobot routes all secret operations through SMS:

  • New secrets created in DataRobot are automatically stored in the configured backend.
  • DataRobot performs a "lazy migration" of pre-existing secrets to the backend lazily on first access. No manual migration is required and consuming services observe no change in behavior. The migration follows these steps:

    1. DataRobot reads the secret from its previous internal store.
    2. The secret is written to the backend via SMS.
    3. The internal reference is updated to point to the backend.
    4. The secret is removed from legacy storage.