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 theTokenRequestAPI and exchange it for a Nebius IAM token using workload federation.auth.serviceAccountCredsSecretRef: read Nebius service account credentials JSON from a KubernetesSecretand exchange it for a Nebius IAM token.auth.tokenSecretRef: read an already issued Nebius IAM token from a KubernetesSecret.
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:
- Create a Kubernetes
ServiceAccount. - Create a Nebius IAM service account and grant it permission to read the required MysteryBox secrets. See the permissions for the MysteryBox get method.
- 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.
- Make sure Nebius can access the issuer's OIDC discovery and JWKS endpoints.
- Make sure the ESO controller can create tokens for the referenced service account (
createonserviceaccounts/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.