Skip to content

Nebius MysteryBox

External Secrets Operator integrates with Nebius MysteryBox.

Authentication

Nebius Mysterybox supports the following authentication methods:

  • auth.workloadIdentity: request a Kubernetes service account token via the TokenRequest API and exchange it for a Nebius IAM token using workload federation.
  • auth.serviceAccountCredsSecretRef: read Nebius service account credentials JSON from a Kubernetes Secret and exchange it for a Nebius IAM token.
  • auth.tokenSecretRef: read an already issued Nebius IAM token from a Kubernetes Secret.

Service Account credentials

Find more about the authorization option following the official documentation.

Before you start, create a service account and grant it permission to read desired secrets in MysteryBox. For details on required roles and permissions, see MysteryBox get method.

You will need to create a Kubernetes Secret with desired auth parameters and structure. The Kubernetes secret must be in a Subject Credentials format:

{
  "subject-credentials": {
    "alg": "RS256",
    "private-key": "-----BEGIN PRIVATE KEY-----\n<private-key>\n-----END PRIVATE KEY-----\n",
    "kid": "<public-key-ID>",
    "iss": "<service_account_ID>",
    "sub": "<service_account_ID>"
  }
}

Follow the instruction to generate the secret. The SecretStore example below uses this authentication method.

Workload Identity

ESO assumes that this Nebius-side federation setup already exists and only performs runtime token exchange.

To use Workload Identity:

  1. Create a Kubernetes ServiceAccount.
  2. Create a Nebius IAM service account and grant it permission to read the required MysteryBox secrets. See the permissions for the MysteryBox get method.
  3. Configure Nebius federated credentials for the Kubernetes service account:
    • use the Kubernetes cluster's service account issuer URL as the OIDC issuer;
    • use system:serviceaccount:<namespace>:<service-account-name> as the federated subject;
    • use the Nebius IAM service account ID as the subject to impersonate.
  4. Make sure Nebius can access the issuer's OIDC discovery and JWKS endpoints.
  5. Make sure the ESO controller can create tokens for the referenced service account (create on serviceaccounts/token).

Reference both service accounts in the store:

auth:
  workloadIdentity:
    serviceAccountRef:
      name: <kubernetes-service-account-name>
    iamServiceAccountID: <nebius-iam-service-account-id>

For a SecretStore, the Kubernetes service account must be in the same namespace as the store. For a ClusterSecretStore, set serviceAccountRef.namespace explicitly.

Examples

SecretStore

First, create a SecretStore with a Nebius MysteryBox backend.

apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
  name: mysterybox
spec:
  provider:
    nebiusmysterybox:
      apiDomain: api.nebius.cloud:443 # In enterprise development or testing environments, replace it with an internal or environment-specific domain
      auth:
        serviceAccountCredsSecretRef:
          name: sa-credentials
          key: sa-credentials-key
      # [OPTIONAL] Use if apiDomain uses an internal/self-signed CA or custom TLS certificate
      caProvider:
        certSecretRef:
          name: <cert-secret>
          key: <cert-secret-key>.crt

Getting a secret by key

You can get a secret by its secretID and key.

apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: mysterybox-external-secret
spec:
  secretStoreRef:
    kind: SecretStore
    name: mysterybox-secretstore
  target:
    name: imported-secret-by-key
    creationPolicy: Owner
  data:
    - secretKey: password
      remoteRef:
        key: mysteryboxSecretID

Getting a full secret (all keys retrieved)

Another way is to get a full secret that will be imported. When fetching the full secret, each key–value pair from MysteryBox is mapped to a separate entry in the target Kubernetes Secret’s data field.

apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: mysterybox-external-secret
spec:
  secretStoreRef:
    kind: SecretStore
    name: mysterybox-secretstore
  target:
    name: imported-secret-map
    creationPolicy: Owner
  dataFrom:
    - extract:
        key: mysteryboxSecretID

Example of a target secret:

apiVersion: v1
kind: Secret
metadata:
  name: <your-k8s-secret-name>
type: Opaque
data:
  <entry-key-1>: <base64-of-value-1>
  <entry-key-2>: <base64-of-value-2>

Additional usage

There is also a possibility to specify Version variable to get a secret.

...
 data:
    - secretKey: <secretKey>
      remoteRef:
        key: <secretID>
        version: <secretVersion>

Tip

When the version field is not specified, a primary version of the secret will be retrieved.