OVHcloud
Secrets Manager
External Secrets Operator integrates with OVHcloud KMS.
This guide demonstrates:
- how to set up a ClusterSecretStore/SecretStore with the OVH provider.
- ExternalSecret use cases with examples.
- PushSecret use cases with examples.
This guide assumes: - External Secrets Operator is already installed - You have access to OVHcloud Secret Manager - Required credentials are already created
SecretStore
OVH provider supports both token and mTLS authentication.
Token authentication:
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: secret-store-ovh
namespace: default
spec:
provider:
ovh:
server: <kms-endpoint>
okmsid: <okms-id>
auth:
token:
tokenSecretRef:
name: ovh-token
key: token
---
apiVersion: v1
kind: Secret
metadata:
name: ovh-token
data:
token: BASE64-TOKEN-VALUE-PLACEHOLDER
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: secret-store-ovh
namespace: default
spec:
provider:
ovh:
server: "https://eu-west-rbx.okms.ovh.net"
okmsid: "734b9b45-8b1a-469c-b140-b10bd6540017"
auth:
mtls:
certSecretRef:
name: ovh-mtls
key: tls.crt
keySecretRef:
name: ovh-mtls
key: tls.key
---
apiVersion: v1
kind: Secret
metadata:
name: ovh-mtls
namespace: default
type: kubernetes.io/tls
data:
tls.crt: BASE64_CERT_PLACEHOLDER # "client certificate value"
tls.key: BASE64_KEY_PLACEHOLDER # "client key value"
Note
A ClusterSecretStore configuration is the same except you must provide the namespace for tokenSecretRef, certSecretRef and keySecretRef according to your chosen authentication method.
ExternalSecret
For these examples, we will assume you have the following secret in your Secret Manager:
{
"path": "creds",
"data": {
"type": "credential",
"users": {
"kevin": {
"token": "kevin token value"
},
"laura": {
"token": "laura token value"
}
}
}
}
path refers to the secret's path in OVH Secret Manager.
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: external-secret-ovh
namespace: default
spec:
secretStoreRef:
name: secret-store-ovh
kind: SecretStore
target:
name: secret-example
data:
- secretKey: foo
remoteRef:
key: creds
version: version
property: property
| Field | Description | Required |
|---|---|---|
| version | Secret version to retrieve | No |
| property | Specific key or nested key in the secret | No |
| secretKey | The key inside the Kubernetes Secret that will hold the secret's value | Yes |
Fetch the whole secret
- Using
spec.dataResulting Kubernetes Secret data:apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: external-secret-ovh namespace: default spec: secretStoreRef: name: secret-store-ovh kind: SecretStore target: name: secret-example data: - secretKey: foo remoteRef: key: creds{ "foo": { "type": "credential", "users": { "kevin": { "token": "kevin token value" }, "laura": { "token": "laura token value" } } } } - Using
spec.dataFrom.extractResulting Kubernetes Secret data:apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: external-secret-ovh namespace: default spec: secretStoreRef: name: secret-store-ovh kind: SecretStore target: name: secret-example dataFrom: - extract: key: creds{ "type": "credential", "users": { "kevin": { "token": "kevin token value" }, "laura": { "token": "laura token value" } } }
Fetch scalar/nested values
- Scalar value using
dataResulting Kubernetes Secret data:apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: external-secret-ovh namespace: default spec: secretStoreRef: name: secret-store-ovh kind: SecretStore target: name: secret-example data: - secretKey: type remoteRef: key: creds property: type{ "type": "credential" } - Nested value using
dataResulting Kubernetes Secret data:apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: external-secret-ovh namespace: default spec: secretStoreRef: name: secret-store-ovh kind: SecretStore target: name: secret-example data: - secretKey: kevin-token remoteRef: key: creds property: users.kevin.token{ "kevin-token": "kevin token value" } - Nested value using
dataFrom.extractResulting Kubernetes Secret data:apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: external-secret-ovh namespace: default spec: secretStoreRef: name: secret-store-ovh kind: SecretStore target: name: secret-example dataFrom: - extract: key: creds property: users{ "kevin": { "token": "kevin token value" }, "laura": { "token": "laura token value" } }
Warning
Scalar values cannot be retrieved using dataFrom.extract because no Kubernetes secret key can be specified, which would imply storing a value without a corresponding key.
Fetch multiple secrets
Extract multiple secrets, with filtering support.
You can filter either by path or/and regular expression. Path filtering occurs first if you use both.
For these examples, we will assume you have the following secrets in your Secret Manager: path/to/secret/secret1, path/to/secret/secret2, path/to/config/config2, path/to/config/config3, secret-example2.
- Path filtering
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: external-secret-ovh
namespace: default
spec:
secretStoreRef:
name: secret-store-ovh
kind: SecretStore
target:
name: secret-example
dataFrom:
- find:
path: "path/to/secret"
{
"path/to/secret/secret1": "secret1 value",
"path/to/secret/secret2": "secret2 value"
}
Note
If path is left empty or is "/", every secret will be retrieved from your Secret Manager.
- Regular expression filtering
Resulting Kubernetes Secret data:
apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: external-secret-ovh namespace: default spec: secretStoreRef: name: secret-store-ovh kind: SecretStore target: name: secret-example dataFrom: - find: name: regexp: "[2-3]"{ "path/to/secret/secret2": "secret2 value", "path/to/config/config2": "config2 value", "path/to/config/config3": "config3 value", "secret-example2": "secret-example2 value" }
Note
If name.regexp is left empty, every secret will be retrieved from your Secret Manager.
- Combination of both
Resulting Kubernetes Secret data:
apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: external-secret-ovh namespace: default spec: secretStoreRef: name: secret-store-ovh kind: SecretStore target: name: secret-example dataFrom: - find: path: "path/to" name: regexp: "2$"{ "path/to/secret/secret2": "secret2 value", "path/to/config/config2": "config2 value" }
Note
When both are combined, path filtering occurs first.
PushSecret
Check-And-Set
Check-And-Set can be enabled/disabled (default: disabled), in the Secret Store configuration:
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: secret-store-ovh
namespace: default
spec:
provider:
ovh:
server: <kms-endpoint>
okmsid: <okms-id>
auth:
token:
tokenSecretRef:
name: ovh-token
key: token
casRequired: true
---
apiVersion: v1
kind: Secret
metadata:
name: ovh-token
data:
token: BASE64_TOKEN_PLACEHOLDER # "token value"
Secret Rotation
apiVersion: generators.external-secrets.io/v1alpha1
kind: Password
metadata:
name: my-password-generator
spec:
length: 32
digits: 5
symbols: 5
symbolCharacters: "-_^$%*รน/;:,?"
noUpper: false
allowRepeat: true
---
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-secret-ovh
spec:
refreshInterval: 6h0m0s
secretStoreRefs:
- name: secret-store-ovh
kind: SecretStore
selector:
generatorRef:
apiVersion: generators.external-secrets.io/v1alpha1
kind: Password
name: my-password-generator
data:
- match:
secretKey: password # property in the generator output
remoteRef:
remoteKey: prod/mysql/password
With this configuration, the secret is automatically rotated every 6 hours in the OVH Secret Manager.
Secret migration
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: secret-store-vault
namespace: default
spec:
provider:
vault:
server: "https://my.vault.server:8200"
path: "secret"
version: "v2"
auth:
tokenSecretRef:
name: vault-token
key: token
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: external-secret-vault
namespace: default
spec:
secretStoreRef:
name: secret-store-vault
kind: SecretStore
refreshPolicy: Periodic
refreshInterval: "10s"
target:
name: creds-secret-vault
dataFrom:
- extract:
key: example
---
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: secret-store-ovh
namespace: default
spec:
provider:
ovh:
server: <kms-endpoint>
okmsid: <okms-id>
auth:
token:
tokenSecretRef:
name: ovh-token
key: token
---
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-secret-ovh
spec:
secretStoreRefs:
- name: secret-store-ovh
kind: SecretStore
selector:
secret:
name: creds-secret-vault
refreshInterval: 10s
data:
- match:
secretKey: "secretKey"
remoteRef:
remoteKey: "creds-secret-migrated"
This example demonstrates how to fetch a secret from a HashiCorp Vault KV secrets engine and sync it into OVH Secret Manager.